We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
CA not running with new image
it seems like CA isn't running right now w/ the switch to Alpine, need to investigate

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `openstates/ca/models.py`
Content:
```
1 from sqlalchemy import (Column, Integer, String, ForeignKey,
2                         DateTime, Numeric, UnicodeText)
3 from sqlalchemy.sql import and_
4 from sqlalchemy.orm import backref, relation
5 from sqlalchemy.ext.declarative import declarative_base
6 
7 from lxml import etree
8 
9 Base = declarative_base()
10 
11 
12 class CABill(Base):
13     __tablename__ = "bill_tbl"
14 
15     bill_id = Column(String(20), primary_key=True)
16     session_year = Column(String(8))
17     session_num = Column(String(2))
18     measure_type = Column(String(4))
19     measure_num = Column(Integer)
20     measure_state = Column(String(40))
21     chapter_year = Column(String(4))
22     chapter_type = Column(String(10))
23     chapter_session_num = Column(String(2))
24     chapter_num = Column(String(10))
25     latest_bill_version_id = Column(String(30))
26     active_flg = Column(String(1))
27     trans_uid = Column(String(30))
28     trans_update = Column(DateTime)
29     current_location = Column(String(200))
30     current_secondary_loc = Column(String(60))
31     current_house = Column(String(60))
32     current_status = Column(String(60))
33 
34     actions = relation('CABillAction', backref=backref('bill'),
35                        order_by="CABillAction.bill_history_id")
36 
37     versions = relation('CABillVersion', backref=backref('bill'),
38                         order_by='desc(CABillVersion.version_num)')
39 
40     votes = relation('CAVoteSummary', backref=backref('bill'),
41                      order_by='CAVoteSummary.vote_date_time')
42 
43     @property
44     def short_bill_id(self):
45         return "%s%d" % (self.measure_type, self.measure_num)
46 
47 
48 class CABillVersion(Base):
49     __tablename__ = "bill_version_tbl"
50 
51     bill_version_id = Column(String(30), primary_key=True)
52     bill_id = Column(String(19), ForeignKey(CABill.bill_id))
53     version_num = Column(Integer)
54     bill_version_action_date = Column(DateTime)
55     bill_version_action = Column(String(100))
56     request_num = Column(String(10))
57     subject = Column(String(1000))
58     vote_required = Column(String(100))
59     appropriation = Column(String(3))
60     fiscal_committee = Column(String(3))
61     local_program = Column(String(3))
62     substantive_changes = Column(String(3))
63     urgency = Column(String(3))
64     taxlevy = Column(String(3))
65     bill_xml = Column(UnicodeText)
66     active_flg = Column(String(1))
67     trans_uid = Column(String(30))
68     trans_update = Column(DateTime)
69 
70     @property
71     def xml(self):
72         if '_xml' not in self.__dict__:
73             self._xml = etree.fromstring(self.bill_xml.encode('utf-8'),
74                                          etree.XMLParser(recover=True))
75         return self._xml
76 
77     @property
78     def title(self):
79         text = self.xml.xpath("string(//*[local-name() = 'Title'])") or ''
80         return text.strip()
81 
82     @property
83     def short_title(self):
84         text = self.xml.xpath("string(//*[local-name() = 'Subject'])") or ''
85         return text.strip()
86 
87 
88 class CABillVersionAuthor(Base):
89     __tablename__ = "bill_version_authors_tbl"
90 
91     # Note: the primary_keys here are a lie - the actual table has no pk
92     # but SQLAlchemy seems to demand one. Furthermore, I get strange
93     # exceptions when trying to use bill_version_id as part of a
94     # composite primary key.
95 
96     bill_version_id = Column(String(30),
97                              ForeignKey(CABillVersion.bill_version_id))
98     type = Column(String(15))
99     house = Column(String(100))
100     name = Column(String(100), primary_key=True)
101     contribution = Column(String(100))
102     committee_members = Column(String(2000))
103     active_flg = Column(String(1))
104     trans_uid = Column(String(30))
105     trans_update = Column(DateTime, primary_key=True)
106     primary_author_flg = Column(String(1))
107 
108     version = relation(CABillVersion, backref=backref('authors'))
109 
110 
111 class CABillAction(Base):
112     __tablename__ = "bill_history_tbl"
113 
114     bill_id = Column(String(20), ForeignKey(CABill.bill_id))
115     bill_history_id = Column(Numeric, primary_key=True)
116     action_date = Column(DateTime)
117     action = Column(String(2000))
118     trans_uid = Column(String(20))
119     trans_update_dt = Column(DateTime)
120     action_sequence = Column(Integer)
121     action_code = Column(String(5))
122     action_status = Column(String(60))
123     primary_location = Column(String(60))
124     secondary_location = Column(String(60))
125     ternary_location = Column(String(60))
126     end_status = Column(String(60))
127 
128     @property
129     def actor(self):
130         # TODO: replace committee codes w/ names
131 
132         if not self.primary_location:
133             return None
134 
135         actor = self.primary_location
136 
137         if self.secondary_location:
138             actor += " (%s" % self.secondary_location
139 
140             if self.ternary_location:
141                 actor += " %s" % self.ternary_location
142 
143             actor += ")"
144 
145         return actor
146 
147 
148 class CALegislator(Base):
149     __tablename__ = 'legislator_tbl'
150 
151     district = Column(String(5), primary_key=True)
152     session_year = Column(String(8), primary_key=True)
153     legislator_name = Column(String(30), primary_key=True)
154     house_type = Column(String(1), primary_key=True)
155     author_name = Column(String(200))
156     first_name = Column(String(30))
157     last_name = Column(String(30))
158     middle_initial = Column(String(1))
159     name_suffix = Column(String(12))
160     name_title = Column(String(34))
161     web_name_title = Column(String(34))
162     party = Column(String(4))
163     active_flg = Column(String(1))
164     trans_uid = Column(String(30))
165     trans_update = Column(DateTime)
166 
167 
168 class CAMotion(Base):
169     __tablename__ = "bill_motion_tbl"
170 
171     motion_id = Column(Integer, primary_key=True)
172     motion_text = Column(String(250))
173     trans_uid = Column(String(30))
174     trans_update = Column(DateTime)
175 
176 
177 class CALocation(Base):
178     __tablename__ = "location_code_tbl"
179 
180     session_year = Column(String(8), primary_key=True)
181     location_code = Column(String(6), primary_key=True)
182     location_type = Column(String(1), primary_key=True)
183     consent_calendar_code = Column(String(2), primary_key=True)
184     description = Column(String(60))
185     long_description = Column(String(200))
186     active_flg = Column(String(1))
187     trans_uid = Column(String(30))
188     trans_update = Column(DateTime)
189 
190 
191 class CAVoteSummary(Base):
192     __tablename__ = "bill_summary_vote_tbl"
193 
194     bill_id = Column(String(20), ForeignKey(CABill.bill_id), primary_key=True)
195     location_code = Column(String(6), ForeignKey(CALocation.location_code), primary_key=True)
196     vote_date_time = Column(DateTime, primary_key=True)
197     vote_date_seq = Column(Integer, primary_key=True)
198     motion_id = Column(Integer, ForeignKey(CAMotion.motion_id), primary_key=True)
199     ayes = Column(Integer)
200     noes = Column(Integer)
201     abstain = Column(Integer)
202     vote_result = Column(String(6))
203     trans_uid = Column(String(30))
204     trans_update = Column(DateTime, primary_key=True)
205 
206     motion = relation(CAMotion)
207     location = relation(CALocation)
208 
209     @property
210     def threshold(self):
211         # This may not always be true...
212         if self.location_code != "AFLOOR" and self.location_code != "SFLOOR":
213             return '1/2'
214 
215         # Get the associated bill version (probably?)
216         version = next(filter(lambda v: v.bill_version_action_date <= self.vote_date_time,
217                               self.bill.versions))
218 
219         if version.vote_required == 'Majority':
220             return '1/2'
221         else:
222             return '2/3'
223 
224 
225 class CAVoteDetail(Base):
226     __tablename__ = "bill_detail_vote_tbl"
227 
228     bill_id = Column(String(20), ForeignKey(CABill.bill_id),
229                      ForeignKey(CAVoteSummary.bill_id), primary_key=True)
230     location_code = Column(String(6), ForeignKey(CAVoteSummary.location_code),
231                            primary_key=True)
232     legislator_name = Column(String(50), primary_key=True)
233     vote_date_time = Column(DateTime, ForeignKey(CAVoteSummary.vote_date_time),
234                             primary_key=True)
235     vote_date_seq = Column(Integer, ForeignKey(CAVoteSummary.vote_date_seq),
236                            primary_key=True)
237     vote_code = Column(String(5), primary_key=True)
238     motion_id = Column(Integer, ForeignKey(CAVoteSummary.motion_id),
239                        primary_key=True)
240     trans_uid = Column(String(30), primary_key=True)
241     trans_update = Column(DateTime, primary_key=True)
242 
243     bill = relation(CABill, backref=backref('detail_votes'))
244     summary = relation(
245         CAVoteSummary,
246         primaryjoin=and_(CAVoteSummary.bill_id == bill_id,
247                          CAVoteSummary.location_code == location_code,
248                          CAVoteSummary.vote_date_time == vote_date_time,
249                          CAVoteSummary.vote_date_seq == vote_date_seq,
250                          CAVoteSummary.motion_id == motion_id),
251         backref=backref('votes'))
252 
253 
254 class CACommitteeHearing(Base):
255     __tablename__ = "committee_hearing_tbl"
256 
257     bill_id = Column(String(20), ForeignKey(CABill.bill_id),
258                      ForeignKey(CAVoteSummary.bill_id), primary_key=True)
259     committee_type = Column(String(2), primary_key=True)
260     committee_nr = Column(Integer, primary_key=True)
261     hearing_date = Column(DateTime, primary_key=True)
262     location_code = Column(String(6), primary_key=True)
263     trans_uid = Column(String(30), primary_key=True)
264     trans_update_date = Column(DateTime, primary_key=True)
265 
266     bill = relation(CABill, backref=backref('committee_hearings'))
267
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/openstates/ca/models.py b/openstates/ca/models.py
--- a/openstates/ca/models.py
+++ b/openstates/ca/models.py
@@ -1,7 +1,7 @@
 from sqlalchemy import (Column, Integer, String, ForeignKey,
                         DateTime, Numeric, UnicodeText)
 from sqlalchemy.sql import and_
-from sqlalchemy.orm import backref, relation
+from sqlalchemy.orm import backref, relation, foreign
 from sqlalchemy.ext.declarative import declarative_base
 
 from lxml import etree
@@ -225,8 +225,7 @@
 class CAVoteDetail(Base):
     __tablename__ = "bill_detail_vote_tbl"
 
-    bill_id = Column(String(20), ForeignKey(CABill.bill_id),
-                     ForeignKey(CAVoteSummary.bill_id), primary_key=True)
+    bill_id = Column(String(20), ForeignKey(CABill.bill_id), primary_key=True)
     location_code = Column(String(6), ForeignKey(CAVoteSummary.location_code),
                            primary_key=True)
     legislator_name = Column(String(50), primary_key=True)
@@ -240,10 +239,12 @@
     trans_uid = Column(String(30), primary_key=True)
     trans_update = Column(DateTime, primary_key=True)
 
-    bill = relation(CABill, backref=backref('detail_votes'))
+    bill = relation(CABill,
+                    primaryjoin="CABill.bill_id == foreign(CAVoteDetail.bill_id)",
+                    backref=backref('detail_votes'))
     summary = relation(
         CAVoteSummary,
-        primaryjoin=and_(CAVoteSummary.bill_id == bill_id,
+        primaryjoin=and_(CAVoteSummary.bill_id == foreign(bill_id),
                          CAVoteSummary.location_code == location_code,
                          CAVoteSummary.vote_date_time == vote_date_time,
                          CAVoteSummary.vote_date_seq == vote_date_seq,

{"golden_diff": "diff --git a/openstates/ca/models.py b/openstates/ca/models.py\n--- a/openstates/ca/models.py\n+++ b/openstates/ca/models.py\n@@ -1,7 +1,7 @@\n from sqlalchemy import (Column, Integer, String, ForeignKey,\n                         DateTime, Numeric, UnicodeText)\n from sqlalchemy.sql import and_\n-from sqlalchemy.orm import backref, relation\n+from sqlalchemy.orm import backref, relation, foreign\n from sqlalchemy.ext.declarative import declarative_base\n \n from lxml import etree\n@@ -225,8 +225,7 @@\n class CAVoteDetail(Base):\n     __tablename__ = \"bill_detail_vote_tbl\"\n \n-    bill_id = Column(String(20), ForeignKey(CABill.bill_id),\n-                     ForeignKey(CAVoteSummary.bill_id), primary_key=True)\n+    bill_id = Column(String(20), ForeignKey(CABill.bill_id), primary_key=True)\n     location_code = Column(String(6), ForeignKey(CAVoteSummary.location_code),\n                            primary_key=True)\n     legislator_name = Column(String(50), primary_key=True)\n@@ -240,10 +239,12 @@\n     trans_uid = Column(String(30), primary_key=True)\n     trans_update = Column(DateTime, primary_key=True)\n \n-    bill = relation(CABill, backref=backref('detail_votes'))\n+    bill = relation(CABill,\n+                    primaryjoin=\"CABill.bill_id == foreign(CAVoteDetail.bill_id)\",\n+                    backref=backref('detail_votes'))\n     summary = relation(\n         CAVoteSummary,\n-        primaryjoin=and_(CAVoteSummary.bill_id == bill_id,\n+        primaryjoin=and_(CAVoteSummary.bill_id == foreign(bill_id),\n                          CAVoteSummary.location_code == location_code,\n                          CAVoteSummary.vote_date_time == vote_date_time,\n                          CAVoteSummary.vote_date_seq == vote_date_seq,\n", "issue": "CA not running with new image\nit seems like CA isn't running right now w/ the switch to Alpine, need to investigate\n", "before_files": [{"content": "from sqlalchemy import (Column, Integer, String, ForeignKey,\n                        DateTime, Numeric, UnicodeText)\nfrom sqlalchemy.sql import and_\nfrom sqlalchemy.orm import backref, relation\nfrom sqlalchemy.ext.declarative import declarative_base\n\nfrom lxml import etree\n\nBase = declarative_base()\n\n\nclass CABill(Base):\n    __tablename__ = \"bill_tbl\"\n\n    bill_id = Column(String(20), primary_key=True)\n    session_year = Column(String(8))\n    session_num = Column(String(2))\n    measure_type = Column(String(4))\n    measure_num = Column(Integer)\n    measure_state = Column(String(40))\n    chapter_year = Column(String(4))\n    chapter_type = Column(String(10))\n    chapter_session_num = Column(String(2))\n    chapter_num = Column(String(10))\n    latest_bill_version_id = Column(String(30))\n    active_flg = Column(String(1))\n    trans_uid = Column(String(30))\n    trans_update = Column(DateTime)\n    current_location = Column(String(200))\n    current_secondary_loc = Column(String(60))\n    current_house = Column(String(60))\n    current_status = Column(String(60))\n\n    actions = relation('CABillAction', backref=backref('bill'),\n                       order_by=\"CABillAction.bill_history_id\")\n\n    versions = relation('CABillVersion', backref=backref('bill'),\n                        order_by='desc(CABillVersion.version_num)')\n\n    votes = relation('CAVoteSummary', backref=backref('bill'),\n                     order_by='CAVoteSummary.vote_date_time')\n\n    @property\n    def short_bill_id(self):\n        return \"%s%d\" % (self.measure_type, self.measure_num)\n\n\nclass CABillVersion(Base):\n    __tablename__ = \"bill_version_tbl\"\n\n    bill_version_id = Column(String(30), primary_key=True)\n    bill_id = Column(String(19), ForeignKey(CABill.bill_id))\n    version_num = Column(Integer)\n    bill_version_action_date = Column(DateTime)\n    bill_version_action = Column(String(100))\n    request_num = Column(String(10))\n    subject = Column(String(1000))\n    vote_required = Column(String(100))\n    appropriation = Column(String(3))\n    fiscal_committee = Column(String(3))\n    local_program = Column(String(3))\n    substantive_changes = Column(String(3))\n    urgency = Column(String(3))\n    taxlevy = Column(String(3))\n    bill_xml = Column(UnicodeText)\n    active_flg = Column(String(1))\n    trans_uid = Column(String(30))\n    trans_update = Column(DateTime)\n\n    @property\n    def xml(self):\n        if '_xml' not in self.__dict__:\n            self._xml = etree.fromstring(self.bill_xml.encode('utf-8'),\n                                         etree.XMLParser(recover=True))\n        return self._xml\n\n    @property\n    def title(self):\n        text = self.xml.xpath(\"string(//*[local-name() = 'Title'])\") or ''\n        return text.strip()\n\n    @property\n    def short_title(self):\n        text = self.xml.xpath(\"string(//*[local-name() = 'Subject'])\") or ''\n        return text.strip()\n\n\nclass CABillVersionAuthor(Base):\n    __tablename__ = \"bill_version_authors_tbl\"\n\n    # Note: the primary_keys here are a lie - the actual table has no pk\n    # but SQLAlchemy seems to demand one. Furthermore, I get strange\n    # exceptions when trying to use bill_version_id as part of a\n    # composite primary key.\n\n    bill_version_id = Column(String(30),\n                             ForeignKey(CABillVersion.bill_version_id))\n    type = Column(String(15))\n    house = Column(String(100))\n    name = Column(String(100), primary_key=True)\n    contribution = Column(String(100))\n    committee_members = Column(String(2000))\n    active_flg = Column(String(1))\n    trans_uid = Column(String(30))\n    trans_update = Column(DateTime, primary_key=True)\n    primary_author_flg = Column(String(1))\n\n    version = relation(CABillVersion, backref=backref('authors'))\n\n\nclass CABillAction(Base):\n    __tablename__ = \"bill_history_tbl\"\n\n    bill_id = Column(String(20), ForeignKey(CABill.bill_id))\n    bill_history_id = Column(Numeric, primary_key=True)\n    action_date = Column(DateTime)\n    action = Column(String(2000))\n    trans_uid = Column(String(20))\n    trans_update_dt = Column(DateTime)\n    action_sequence = Column(Integer)\n    action_code = Column(String(5))\n    action_status = Column(String(60))\n    primary_location = Column(String(60))\n    secondary_location = Column(String(60))\n    ternary_location = Column(String(60))\n    end_status = Column(String(60))\n\n    @property\n    def actor(self):\n        # TODO: replace committee codes w/ names\n\n        if not self.primary_location:\n            return None\n\n        actor = self.primary_location\n\n        if self.secondary_location:\n            actor += \" (%s\" % self.secondary_location\n\n            if self.ternary_location:\n                actor += \" %s\" % self.ternary_location\n\n            actor += \")\"\n\n        return actor\n\n\nclass CALegislator(Base):\n    __tablename__ = 'legislator_tbl'\n\n    district = Column(String(5), primary_key=True)\n    session_year = Column(String(8), primary_key=True)\n    legislator_name = Column(String(30), primary_key=True)\n    house_type = Column(String(1), primary_key=True)\n    author_name = Column(String(200))\n    first_name = Column(String(30))\n    last_name = Column(String(30))\n    middle_initial = Column(String(1))\n    name_suffix = Column(String(12))\n    name_title = Column(String(34))\n    web_name_title = Column(String(34))\n    party = Column(String(4))\n    active_flg = Column(String(1))\n    trans_uid = Column(String(30))\n    trans_update = Column(DateTime)\n\n\nclass CAMotion(Base):\n    __tablename__ = \"bill_motion_tbl\"\n\n    motion_id = Column(Integer, primary_key=True)\n    motion_text = Column(String(250))\n    trans_uid = Column(String(30))\n    trans_update = Column(DateTime)\n\n\nclass CALocation(Base):\n    __tablename__ = \"location_code_tbl\"\n\n    session_year = Column(String(8), primary_key=True)\n    location_code = Column(String(6), primary_key=True)\n    location_type = Column(String(1), primary_key=True)\n    consent_calendar_code = Column(String(2), primary_key=True)\n    description = Column(String(60))\n    long_description = Column(String(200))\n    active_flg = Column(String(1))\n    trans_uid = Column(String(30))\n    trans_update = Column(DateTime)\n\n\nclass CAVoteSummary(Base):\n    __tablename__ = \"bill_summary_vote_tbl\"\n\n    bill_id = Column(String(20), ForeignKey(CABill.bill_id), primary_key=True)\n    location_code = Column(String(6), ForeignKey(CALocation.location_code), primary_key=True)\n    vote_date_time = Column(DateTime, primary_key=True)\n    vote_date_seq = Column(Integer, primary_key=True)\n    motion_id = Column(Integer, ForeignKey(CAMotion.motion_id), primary_key=True)\n    ayes = Column(Integer)\n    noes = Column(Integer)\n    abstain = Column(Integer)\n    vote_result = Column(String(6))\n    trans_uid = Column(String(30))\n    trans_update = Column(DateTime, primary_key=True)\n\n    motion = relation(CAMotion)\n    location = relation(CALocation)\n\n    @property\n    def threshold(self):\n        # This may not always be true...\n        if self.location_code != \"AFLOOR\" and self.location_code != \"SFLOOR\":\n            return '1/2'\n\n        # Get the associated bill version (probably?)\n        version = next(filter(lambda v: v.bill_version_action_date <= self.vote_date_time,\n                              self.bill.versions))\n\n        if version.vote_required == 'Majority':\n            return '1/2'\n        else:\n            return '2/3'\n\n\nclass CAVoteDetail(Base):\n    __tablename__ = \"bill_detail_vote_tbl\"\n\n    bill_id = Column(String(20), ForeignKey(CABill.bill_id),\n                     ForeignKey(CAVoteSummary.bill_id), primary_key=True)\n    location_code = Column(String(6), ForeignKey(CAVoteSummary.location_code),\n                           primary_key=True)\n    legislator_name = Column(String(50), primary_key=True)\n    vote_date_time = Column(DateTime, ForeignKey(CAVoteSummary.vote_date_time),\n                            primary_key=True)\n    vote_date_seq = Column(Integer, ForeignKey(CAVoteSummary.vote_date_seq),\n                           primary_key=True)\n    vote_code = Column(String(5), primary_key=True)\n    motion_id = Column(Integer, ForeignKey(CAVoteSummary.motion_id),\n                       primary_key=True)\n    trans_uid = Column(String(30), primary_key=True)\n    trans_update = Column(DateTime, primary_key=True)\n\n    bill = relation(CABill, backref=backref('detail_votes'))\n    summary = relation(\n        CAVoteSummary,\n        primaryjoin=and_(CAVoteSummary.bill_id == bill_id,\n                         CAVoteSummary.location_code == location_code,\n                         CAVoteSummary.vote_date_time == vote_date_time,\n                         CAVoteSummary.vote_date_seq == vote_date_seq,\n                         CAVoteSummary.motion_id == motion_id),\n        backref=backref('votes'))\n\n\nclass CACommitteeHearing(Base):\n    __tablename__ = \"committee_hearing_tbl\"\n\n    bill_id = Column(String(20), ForeignKey(CABill.bill_id),\n                     ForeignKey(CAVoteSummary.bill_id), primary_key=True)\n    committee_type = Column(String(2), primary_key=True)\n    committee_nr = Column(Integer, primary_key=True)\n    hearing_date = Column(DateTime, primary_key=True)\n    location_code = Column(String(6), primary_key=True)\n    trans_uid = Column(String(30), primary_key=True)\n    trans_update_date = Column(DateTime, primary_key=True)\n\n    bill = relation(CABill, backref=backref('committee_hearings'))\n", "path": "openstates/ca/models.py"}], "after_files": [{"content": "from sqlalchemy import (Column, Integer, String, ForeignKey,\n                        DateTime, Numeric, UnicodeText)\nfrom sqlalchemy.sql import and_\nfrom sqlalchemy.orm import backref, relation, foreign\nfrom sqlalchemy.ext.declarative import declarative_base\n\nfrom lxml import etree\n\nBase = declarative_base()\n\n\nclass CABill(Base):\n    __tablename__ = \"bill_tbl\"\n\n    bill_id = Column(String(20), primary_key=True)\n    session_year = Column(String(8))\n    session_num = Column(String(2))\n    measure_type = Column(String(4))\n    measure_num = Column(Integer)\n    measure_state = Column(String(40))\n    chapter_year = Column(String(4))\n    chapter_type = Column(String(10))\n    chapter_session_num = Column(String(2))\n    chapter_num = Column(String(10))\n    latest_bill_version_id = Column(String(30))\n    active_flg = Column(String(1))\n    trans_uid = Column(String(30))\n    trans_update = Column(DateTime)\n    current_location = Column(String(200))\n    current_secondary_loc = Column(String(60))\n    current_house = Column(String(60))\n    current_status = Column(String(60))\n\n    actions = relation('CABillAction', backref=backref('bill'),\n                       order_by=\"CABillAction.bill_history_id\")\n\n    versions = relation('CABillVersion', backref=backref('bill'),\n                        order_by='desc(CABillVersion.version_num)')\n\n    votes = relation('CAVoteSummary', backref=backref('bill'),\n                     order_by='CAVoteSummary.vote_date_time')\n\n    @property\n    def short_bill_id(self):\n        return \"%s%d\" % (self.measure_type, self.measure_num)\n\n\nclass CABillVersion(Base):\n    __tablename__ = \"bill_version_tbl\"\n\n    bill_version_id = Column(String(30), primary_key=True)\n    bill_id = Column(String(19), ForeignKey(CABill.bill_id))\n    version_num = Column(Integer)\n    bill_version_action_date = Column(DateTime)\n    bill_version_action = Column(String(100))\n    request_num = Column(String(10))\n    subject = Column(String(1000))\n    vote_required = Column(String(100))\n    appropriation = Column(String(3))\n    fiscal_committee = Column(String(3))\n    local_program = Column(String(3))\n    substantive_changes = Column(String(3))\n    urgency = Column(String(3))\n    taxlevy = Column(String(3))\n    bill_xml = Column(UnicodeText)\n    active_flg = Column(String(1))\n    trans_uid = Column(String(30))\n    trans_update = Column(DateTime)\n\n    @property\n    def xml(self):\n        if '_xml' not in self.__dict__:\n            self._xml = etree.fromstring(self.bill_xml.encode('utf-8'),\n                                         etree.XMLParser(recover=True))\n        return self._xml\n\n    @property\n    def title(self):\n        text = self.xml.xpath(\"string(//*[local-name() = 'Title'])\") or ''\n        return text.strip()\n\n    @property\n    def short_title(self):\n        text = self.xml.xpath(\"string(//*[local-name() = 'Subject'])\") or ''\n        return text.strip()\n\n\nclass CABillVersionAuthor(Base):\n    __tablename__ = \"bill_version_authors_tbl\"\n\n    # Note: the primary_keys here are a lie - the actual table has no pk\n    # but SQLAlchemy seems to demand one. Furthermore, I get strange\n    # exceptions when trying to use bill_version_id as part of a\n    # composite primary key.\n\n    bill_version_id = Column(String(30),\n                             ForeignKey(CABillVersion.bill_version_id))\n    type = Column(String(15))\n    house = Column(String(100))\n    name = Column(String(100), primary_key=True)\n    contribution = Column(String(100))\n    committee_members = Column(String(2000))\n    active_flg = Column(String(1))\n    trans_uid = Column(String(30))\n    trans_update = Column(DateTime, primary_key=True)\n    primary_author_flg = Column(String(1))\n\n    version = relation(CABillVersion, backref=backref('authors'))\n\n\nclass CABillAction(Base):\n    __tablename__ = \"bill_history_tbl\"\n\n    bill_id = Column(String(20), ForeignKey(CABill.bill_id))\n    bill_history_id = Column(Numeric, primary_key=True)\n    action_date = Column(DateTime)\n    action = Column(String(2000))\n    trans_uid = Column(String(20))\n    trans_update_dt = Column(DateTime)\n    action_sequence = Column(Integer)\n    action_code = Column(String(5))\n    action_status = Column(String(60))\n    primary_location = Column(String(60))\n    secondary_location = Column(String(60))\n    ternary_location = Column(String(60))\n    end_status = Column(String(60))\n\n    @property\n    def actor(self):\n        # TODO: replace committee codes w/ names\n\n        if not self.primary_location:\n            return None\n\n        actor = self.primary_location\n\n        if self.secondary_location:\n            actor += \" (%s\" % self.secondary_location\n\n            if self.ternary_location:\n                actor += \" %s\" % self.ternary_location\n\n            actor += \")\"\n\n        return actor\n\n\nclass CALegislator(Base):\n    __tablename__ = 'legislator_tbl'\n\n    district = Column(String(5), primary_key=True)\n    session_year = Column(String(8), primary_key=True)\n    legislator_name = Column(String(30), primary_key=True)\n    house_type = Column(String(1), primary_key=True)\n    author_name = Column(String(200))\n    first_name = Column(String(30))\n    last_name = Column(String(30))\n    middle_initial = Column(String(1))\n    name_suffix = Column(String(12))\n    name_title = Column(String(34))\n    web_name_title = Column(String(34))\n    party = Column(String(4))\n    active_flg = Column(String(1))\n    trans_uid = Column(String(30))\n    trans_update = Column(DateTime)\n\n\nclass CAMotion(Base):\n    __tablename__ = \"bill_motion_tbl\"\n\n    motion_id = Column(Integer, primary_key=True)\n    motion_text = Column(String(250))\n    trans_uid = Column(String(30))\n    trans_update = Column(DateTime)\n\n\nclass CALocation(Base):\n    __tablename__ = \"location_code_tbl\"\n\n    session_year = Column(String(8), primary_key=True)\n    location_code = Column(String(6), primary_key=True)\n    location_type = Column(String(1), primary_key=True)\n    consent_calendar_code = Column(String(2), primary_key=True)\n    description = Column(String(60))\n    long_description = Column(String(200))\n    active_flg = Column(String(1))\n    trans_uid = Column(String(30))\n    trans_update = Column(DateTime)\n\n\nclass CAVoteSummary(Base):\n    __tablename__ = \"bill_summary_vote_tbl\"\n\n    bill_id = Column(String(20), ForeignKey(CABill.bill_id), primary_key=True)\n    location_code = Column(String(6), ForeignKey(CALocation.location_code), primary_key=True)\n    vote_date_time = Column(DateTime, primary_key=True)\n    vote_date_seq = Column(Integer, primary_key=True)\n    motion_id = Column(Integer, ForeignKey(CAMotion.motion_id), primary_key=True)\n    ayes = Column(Integer)\n    noes = Column(Integer)\n    abstain = Column(Integer)\n    vote_result = Column(String(6))\n    trans_uid = Column(String(30))\n    trans_update = Column(DateTime, primary_key=True)\n\n    motion = relation(CAMotion)\n    location = relation(CALocation)\n\n    @property\n    def threshold(self):\n        # This may not always be true...\n        if self.location_code != \"AFLOOR\" and self.location_code != \"SFLOOR\":\n            return '1/2'\n\n        # Get the associated bill version (probably?)\n        version = next(filter(lambda v: v.bill_version_action_date <= self.vote_date_time,\n                              self.bill.versions))\n\n        if version.vote_required == 'Majority':\n            return '1/2'\n        else:\n            return '2/3'\n\n\nclass CAVoteDetail(Base):\n    __tablename__ = \"bill_detail_vote_tbl\"\n\n    bill_id = Column(String(20), ForeignKey(CABill.bill_id), primary_key=True)\n    location_code = Column(String(6), ForeignKey(CAVoteSummary.location_code),\n                           primary_key=True)\n    legislator_name = Column(String(50), primary_key=True)\n    vote_date_time = Column(DateTime, ForeignKey(CAVoteSummary.vote_date_time),\n                            primary_key=True)\n    vote_date_seq = Column(Integer, ForeignKey(CAVoteSummary.vote_date_seq),\n                           primary_key=True)\n    vote_code = Column(String(5), primary_key=True)\n    motion_id = Column(Integer, ForeignKey(CAVoteSummary.motion_id),\n                       primary_key=True)\n    trans_uid = Column(String(30), primary_key=True)\n    trans_update = Column(DateTime, primary_key=True)\n\n    bill = relation(CABill,\n                    primaryjoin=\"CABill.bill_id == foreign(CAVoteDetail.bill_id)\",\n                    backref=backref('detail_votes'))\n    summary = relation(\n        CAVoteSummary,\n        primaryjoin=and_(CAVoteSummary.bill_id == foreign(bill_id),\n                         CAVoteSummary.location_code == location_code,\n                         CAVoteSummary.vote_date_time == vote_date_time,\n                         CAVoteSummary.vote_date_seq == vote_date_seq,\n                         CAVoteSummary.motion_id == motion_id),\n        backref=backref('votes'))\n\n\nclass CACommitteeHearing(Base):\n    __tablename__ = \"committee_hearing_tbl\"\n\n    bill_id = Column(String(20), ForeignKey(CABill.bill_id),\n                     ForeignKey(CAVoteSummary.bill_id), primary_key=True)\n    committee_type = Column(String(2), primary_key=True)\n    committee_nr = Column(Integer, primary_key=True)\n    hearing_date = Column(DateTime, primary_key=True)\n    location_code = Column(String(6), primary_key=True)\n    trans_uid = Column(String(30), primary_key=True)\n    trans_update_date = Column(DateTime, primary_key=True)\n\n    bill = relation(CABill, backref=backref('committee_hearings'))\n", "path": "openstates/ca/models.py"}]}