{"action":"created","comment":{"url":"https://api.github.com/repos/Recidiviz/recidiviz-data/pulls/comments/239147037","pull_request_review_id":181859257,"id":239147037,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzOTE0NzAzNw==","diff_hunk":"@@ -14,141 +14,415 @@\n # You should have received a copy of the GNU General Public License\n # along with this program.  If not, see <https://www.gnu.org/licenses/>.\n # ============================================================================\n-\"\"\"Define the ORM schema objects that map directly to the database.\"\"\"\n-\n-from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey\n+\"\"\"Define the ORM schema objects that map directly to the database.\n+\n+The below schema uses only generic SQLAlchemy types, and therefore should be\n+portable between database implementations.\n+\n+NOTE: Many of the tables in the below schema are historical tables. Historical\n+tables have no primary key. Their equivalent of the primary key from the\n+corresponding master table is non-unique. A composite primary key could\n+technically be generated from the ID and the period columns, but there would be\n+no benefit from it, as that would require any foreign key relationship to\n+directly use the period columns, which is contrary to the purpose of the\n+temporal table design. Because of this non-uniqueness, any foreign key\n+pointing to a historical table does NOT have a foreign key constraint.\n+\"\"\"\n+\n+from sqlalchemy import Boolean, Column, Date, DateTime, Enum, ForeignKey, \\\n+    Integer, String\n from sqlalchemy.ext.declarative import declarative_base\n from sqlalchemy.orm import relationship\n \n+\n+# Enum values. Exposed separately from the SQLAlchemy Enum that owns them for\n+# easier access to the values.\n+#\n+# These values should not be used directly by application code, but should be\n+# mapped to application layer enums in order to maintain decoupling between\n+# the application and database.\n+#\n+# TODO: replace with Python enums after converting to Python 3\n+\n+# Person\n+gender = ('Female',\n+          'Male')\n+race = ('American Indian/Alaskan Native',\n+        'Asian',\n+        'Black',\n+        'Native Hawaiian/Pacific Islander',\n+        'Other',\n+        'White')\n+ethnicity = ('Hispanic',\n+             'Not Hispanic')\n+\n+# Booking\n+release_reason = ('Bond',\n+                  'Death',\n+                  'Escape',\n+                  'Expiration of Sentence',\n+                  'Own Recognizance',\n+                  'Parole',\n+                  'Probation',\n+                  'Transfer')\n+custody_status = ('Escaped',\n+                  'Held Elsewhere',\n+                  'In Custody',\n+                  'Released')\n+classification = ('High',\n+                  'Low',\n+                  'Maximum',\n+                  'Medium',\n+                  'Minimum',\n+                  'Work Release')\n+\n+# Hold\n+hold_status = ('Active',\n+               'Inactive')\n+\n+# Bond\n+bond_type = ('Bond Denied',\n+             'Cash',\n+             'No Bond',\n+             'Secured',\n+             'Unsecured')\n+bond_status = ('Active',\n+               'Posted')\n+\n+# SentenceRelationship\n+sentence_relationship_type = ('Concurrent',\n+                              'Consecutive')\n+\n+# Charge\n+degree = ('First',\n+          'Second',\n+          'Third')\n+charge_class = ('Felony',\n+                'Misdemenor',\n+                'Parole Violation',\n+                'Probation Violation')\n+charge_status = ('Acquitted',\n+                 'Completed Sentence',\n+                 'Convicted',\n+                 'Dropped',\n+                 'Pending',\n+                 'Pretrial',\n+                 'Sentenced')\n+court_type = ('Circuit',\n+              'District',\n+              'Other',\n+              'Superior')\n+\n+\n+# SQLAlchemy enums. Created separately from the tables so they can be shared\n+# between the master and historical tables for each entity.\n+bond_status_enum = Enum(*bond_status, name='bond_status')\n+bond_type_enum = Enum(*bond_type, name='bond_type')\n+charge_class_enum = Enum(*charge_class, name='charge_class')\n+charge_status_enum = Enum(*charge_status, name='charge_status')\n+classification_enum = Enum(*classification, name='classification')\n+court_type_enum = Enum(*court_type, name='court_type')\n+custody_status_enum = Enum(*custody_status, name='custody_status')\n+degree_enum = Enum(*degree, name='degree')\n+ethnicity_enum = Enum(*ethnicity, name='ethnicity')\n+gender_enum = Enum(*gender, name='gender')\n+hold_status_enum = Enum(*hold_status, name='hold_status')\n+race_enum = Enum(*race, name='race')\n+release_reason_enum = Enum(*release_reason, name='release_reason')\n+sentence_relationship_type_enum = Enum(\n+    *sentence_relationship_type, name='sentence_relationship_type')\n+\n+\n+# Base class for all table classes\n Base = declarative_base()\n \n \n class Person(Base):\n-    \"\"\"Represents a Person as defined by our SQL schema\"\"\"\n-    __tablename__ = 'people'\n-\n-    person_id = Column('person_id', Integer, primary_key=True)\n-\n-    scraped_person_id = Column('scraped_person_id', Integer)\n-    surname = Column('surname', String)\n-    given_names = Column('given_names', String)\n-    birthdate = Column('birthdate', DateTime)\n-    birthdate_inferred_from_age = Column('birthdate_inferred_from_age',\n-                                         Boolean)\n-    race = Column('race', String)\n-    ethnicity = Column('ethnicity', String)\n-    place_of_residence = Column('place_of_residence', String)\n-\n-    bookings = relationship('Booking')\n+    \"\"\"Represents a person in the SQL schema\"\"\"\n+    __tablename__ = 'Person'\n+\n+    person_id = Column(Integer, primary_key=True)\n+    surname = Column(String(255))\n+    given_names = Column(String(255))\n+    birthdate = Column(Date)\n+    birthdate_inferred_from_age = Column(Boolean)\n+    gender = Column(gender_enum)\n+    race = Column(race_enum)\n+    ethnicity = Column(ethnicity_enum)\n+    place_of_residence = Column(String(255))\n+\n+    bookings = relationship('Booking', back_populates='person')\n+\n+\n+class PersonHistory(Base):\n+    \"\"\"Represents the historical state of a person\"\"\"\n+    __tablename__ = 'PersonHistory'\n+\n+    person_id = Column(Integer, nullable=False, index=True)\n+    surname = Column(String(255))\n+    given_names = Column(String(255))\n+    birthdate = Column(Date)\n+    birthdate_inferred_from_age = Column(Boolean)\n+    gender = Column(gender_enum)\n+    race = Column(race_enum)\n+    ethnicity = Column(ethnicity_enum)\n+    place_of_residence = Column(String(255))\n+    valid_from = Column(DateTime, nullable=False)\n+    valid_to = Column(DateTime)\n \n \n class Booking(Base):\n-    \"\"\"Represents a Booking as defined by our SQL schema\"\"\"\n-    __tablename__ = 'bookings'\n+    \"\"\"Represents a booking in the SQL schema\"\"\"\n+    __tablename__ = 'Booking'\n+\n+    booking_id = Column(Integer, primary_key=True)\n+    person_id = Column(Integer, ForeignKey('Person.person_id'), nullable=False)\n+    admission_date = Column(Date)\n+    release_date = Column(Date)\n+    projected_release_date = Column(Date)\n+    release_reason = Column(release_reason_enum)\n+    custody_status = Column(custody_status_enum, nullable=False)\n+    held_for_other_jurisdiction = Column(Boolean)\n+    facility = Column(String(255))\n+    classification = Column(classification_enum)\n+    region = Column(String(255), nullable=False)\n+    last_scraped_date = Column(Date, nullable=False)\n+\n+    person = relationship('Person', back_populates='bookings')\n+    holds = relationship('Hold', back_populates='booking')\n+    arrest = relationship('Arrest', uselist=False, back_populates='booking')\n+    charges = relationship('Charge', back_populates='booking')\n+\n+\n+class BookingHistory(Base):\n+    \"\"\"Represents the historical state of a booking\"\"\"\n+    __tablename__ = 'BookingHistory'\n+\n+    # NOTE: BookingHistory does not contain last_scraped_date column\n+\n+    booking_id = Column(Integer, nullable=False, index=True)\n+    person_id = Column(Integer, nullable=False, index=True)\n+    admission_date = Column(Date)\n+    release_date = Column(Date)\n+    projected_release_date = Column(Date)\n+    release_reason = Column(release_reason_enum)\n+    custody_status = Column(custody_status_enum, nullable=False)\n+    held_for_other_jurisdiction = Column(Boolean)\n+    facility = Column(String(255))\n+    classification = Column(classification_enum)\n+    region = Column(String(255), nullable=False)\n+    valid_from = Column(DateTime, nullable=False)\n+    valid_to = Column(DateTime)\n+\n+\n+class Hold(Base):\n+    \"\"\"Represents a hold from another jurisdiction against a booking\"\"\"\n+    __tablename__ = 'Hold'\n+\n+    hold_id = Column(Integer, primary_key=True)\n+    booking_id = Column(\n+        Integer, ForeignKey('Booking.booking_id'), nullable=False)\n+    jurisdiction_name = Column(String(255))\n+    hold_status = Column(hold_status_enum, nullable=False)\n+\n+    booking = relationship('Booking', back_populates='holds')\n+\n+\n+class HoldHistory(Base):\n+    \"\"\"Represents the historical state of a hold\"\"\"\n+    __tablename__ = 'HoldHistory'\n+\n+    hold_id = Column(Integer, nullable=False, index=True)\n+    booking_id = Column(Integer, nullable=False, index=True)\n+    jurisdiction_name = Column(String(255))\n+    hold_status = Column(hold_status_enum, nullable=False)\n+    valid_from = Column(DateTime, nullable=False)\n+    valid_to = Column(DateTime)\n \n-    booking_id = Column('booking_id', Integer, primary_key=True)\n \n-    person_id = Column('person_id', Integer,\n-                       ForeignKey(\"people.person_id\"))\n+class Arrest(Base):\n+    \"\"\"Represents an arrest in the SQL schema\"\"\"\n+    __tablename__ = 'Arrest'\n \n-    admission_date = Column('admission_date', DateTime)\n-    release_date = Column('release_date', DateTime)\n-    release_date_type = Column('release_date_type', String)\n-    release_reason = Column('release_reason', String)\n-    custody_status = Column('custody_status', String)\n-    held_for_other_jurisdiction = Column('held_for_other_jurisdiction',\n-                                         Boolean)\n-    hold = Column('hold', String)\n-    facility = Column('facility', String)\n-    classification = Column('classification', String)\n+    arrest_id = Column(Integer, primary_key=True)\n+    booking_id = Column(\n+        Integer, ForeignKey('Booking.booking_id'), nullable=False)\n+    date = Column(Date)\n+    location = Column(String(255))\n+    agency = Column(String(255))\n+    officer_name = Column(String(255))\n+    officer_id = Column(String(255))\n \n-    region = Column('region', String)\n-    last_scraped_date = Column('last_scraped_date', DateTime)\n+    booking = relationship('Booking', back_populates='arrest')\n \n-    arrest = relationship('Arrest', uselist=False)\n-    charges = relationship('Charge')\n \n+class ArrestHistory(Base):\n+    \"\"\"Represents the historical state of an arrest\"\"\"\n+    __tablename__ = 'ArrestHistory'\n \n-class Arrest(Base):\n-    \"\"\"Represents and Arrest as defined by our SQL schema\"\"\"\n-    __tablename__ = 'arrests'\n+    arrest_id = Column(Integer, nullable=False, index=True)\n+    booking_id = Column(Integer, nullable=False, index=True)\n+    date = Column(Date)\n+    location = Column(String(255))\n+    agency = Column(String(255))\n+    officer_name = Column(String(255))\n+    officer_id = Column(String(255))\n+    valid_from = Column(DateTime, nullable=False)\n+    valid_to = Column(DateTime)\n \n-    arrest_id = Column('arrest_id', Integer, primary_key=True)\n \n-    booking_id = Column('booking_id', Integer,\n-                        ForeignKey(\"bookings.booking_id\"))\n+class Bond(Base):\n+    \"\"\"Represents a bond in the SQL schema\"\"\"\n+    __tablename__ = 'Bond'\n \n-    date = Column('date', DateTime)\n-    location = Column('location', String)\n-    agency = Column('agency', String)\n-    officer_name = Column('officer_name', String)\n-    officer_id = Column('officer_id', String)\n+    bond_id = Column(Integer, primary_key=True)\n+    amount_dollars = Column(Integer)\n+    bond_type = Column(bond_type_enum)\n+    status = Column(bond_status_enum, nullable=False)\n \n+    charges = relationship('Charge', back_populates='bond')\n \n-class Charge(Base):\n-    \"\"\"Represents a Change as defined by our SQL schema\"\"\"\n-    __tablename__ = 'charges'\n-\n-    charge_id = Column('charge_id', Integer, primary_key=True)\n-\n-    booking_id = Column('booking_id', Integer,\n-                        ForeignKey(\"bookings.booking_id\"))\n-\n-    # Define many-to-one Foreign Keys\n-    bond_id = Column('bond_id', Integer, ForeignKey(\"bonds.bond_id\"))\n-    sentence_id = Column('sentence_id', Integer,\n-                         ForeignKey(\"sentences.sentence_id\"))\n-\n-    offence_date = Column('offence_date', DateTime)\n-    statute = Column('statute', String)\n-    offense_code = Column('offense_code', Integer)\n-    name = Column('name', String)\n-    attempted = Column('attempted', Boolean)\n-    degree = Column('degree', String)\n-    charge_class = Column('charge_class', String)\n-    level = Column('level', String)\n-    fee = Column('fee', Integer)\n-    charging_entity = Column('charging_entity', String)\n-    status = Column('status', String)\n-    number_of_counts = Column('number_of_counts', Integer)\n-    court_type = Column('court_type', String)\n-    case_number = Column('case_number', String)\n-    next_court_date = Column('next_court_date', DateTime)\n-    judge_name = Column('judge_name', String)\n-\n-    bond = relationship('Bond')\n-    sentence = relationship('Sentence')\n \n+class BondHistory(Base):\n+    \"\"\"Represents the historical state of a bond\"\"\"\n+    __tablename__ = 'BondHistory'\n \n-class Bond(Base):\n-    \"\"\"Represents a Bond as defined by our SQL schema\"\"\"\n-    __tablename__ = 'bonds'\n+    bond_id = Column(Integer, nullable=False, index=True)\n+    amount_dollars = Column(Integer)\n+    bond_type = Column(bond_type_enum)\n+    status = Column(bond_status_enum, nullable=False)\n+    valid_from = Column(DateTime, nullable=False)\n+    valid_to = Column(DateTime)\n \n-    bond_id = Column('bond_id', Integer, primary_key=True)\n \n-    amount = Column('amount', Integer)\n-    bond_type = Column('bond_type', String)\n-    status = Column('status', String)\n+class Sentence(Base):\n+    \"\"\"Represents a sentence in the SQL schema\"\"\"\n+    __tablename__ = 'Sentence'\n+\n+    sentence_id = Column(Integer, primary_key=True)\n+    date_imposed = Column(Date)\n+    min_length_days = Column(Integer)\n+    max_length_days = Column(Integer)\n+    is_life = Column(Boolean)\n+    is_probation = Column(Boolean)\n+    is_suspended = Column(Boolean)\n+    fine_dollars = Column(Integer)\n+    parole_possible = Column(Boolean)\n+    post_release_supervision_length_days = Column(Integer)\n+\n+    charges = relationship('Charge', back_populates='sentence')\n+    related_sentences = relationship(\n+        'SentenceRelationship', back_populates='related_sentences')\n+\n+\n+class SentenceHistory(Base):\n+    \"\"\"Represents the historical state of a sentence\"\"\"\n+    __tablename__ = 'SentenceHistory'\n+\n+    sentence_id = Column(Integer, nullable=False, index=True)\n+    date_imposed = Column(Date)\n+    min_length_days = Column(Integer)\n+    max_length_days = Column(Integer)\n+    is_life = Column(Boolean)\n+    is_probation = Column(Boolean)\n+    is_suspended = Column(Boolean)\n+    fine_dollars = Column(Integer)\n+    parole_possible = Column(Boolean)\n+    post_release_supervision_length_days = Column(Integer)\n+    valid_from = Column(DateTime, nullable=False)\n+    valid_to = Column(DateTime)\n+\n+\n+class SentenceRelationship(Base):\n+    \"\"\"Represents the relationship between two sentences\"\"\"\n+    __tablename__ = 'SentenceRelationship'\n+\n+    # NOTE: (A,B) is equal to (B,A). There should only be one","path":"recidiviz/persistence/database/schema.py","position":416,"original_position":416,"commit_id":"7ee8706a12f436887f9710b02387b166bb375a28","original_commit_id":"7ee8706a12f436887f9710b02387b166bb375a28","user":{"login":"jessex","id":431895,"node_id":"MDQ6VXNlcjQzMTg5NQ==","avatar_url":"https://avatars1.githubusercontent.com/u/431895?v=4","gravatar_id":"","url":"https://api.github.com/users/jessex","html_url":"https://github.com/jessex","followers_url":"https://api.github.com/users/jessex/followers","following_url":"https://api.github.com/users/jessex/following{/other_user}","gists_url":"https://api.github.com/users/jessex/gists{/gist_id}","starred_url":"https://api.github.com/users/jessex/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jessex/subscriptions","organizations_url":"https://api.github.com/users/jessex/orgs","repos_url":"https://api.github.com/users/jessex/repos","events_url":"https://api.github.com/users/jessex/events{/privacy}","received_events_url":"https://api.github.com/users/jessex/received_events","type":"User","site_admin":false},"body":"Mm, yeah, slightly annoying. I imagine this is an entity that we'll create with most every booking, too? Maybe leave this as-is until we know we're running into issues otherwise.","created_at":"2018-12-05T16:46:44Z","updated_at":"2018-12-05T16:46:44Z","html_url":"https://github.com/Recidiviz/recidiviz-data/pull/251#discussion_r239147037","pull_request_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/pulls/251","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/Recidiviz/recidiviz-data/pulls/comments/239147037"},"html":{"href":"https://github.com/Recidiviz/recidiviz-data/pull/251#discussion_r239147037"},"pull_request":{"href":"https://api.github.com/repos/Recidiviz/recidiviz-data/pulls/251"}},"in_reply_to_id":238937356},"pull_request":{"url":"https://api.github.com/repos/Recidiviz/recidiviz-data/pulls/251","id":235973014,"node_id":"MDExOlB1bGxSZXF1ZXN0MjM1OTczMDE0","html_url":"https://github.com/Recidiviz/recidiviz-data/pull/251","diff_url":"https://github.com/Recidiviz/recidiviz-data/pull/251.diff","patch_url":"https://github.com/Recidiviz/recidiviz-data/pull/251.patch","issue_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/issues/251","number":251,"state":"open","locked":false,"title":"Update SQLAlchemy schema","user":{"login":"zdg2102","id":15900150,"node_id":"MDQ6VXNlcjE1OTAwMTUw","avatar_url":"https://avatars0.githubusercontent.com/u/15900150?v=4","gravatar_id":"","url":"https://api.github.com/users/zdg2102","html_url":"https://github.com/zdg2102","followers_url":"https://api.github.com/users/zdg2102/followers","following_url":"https://api.github.com/users/zdg2102/following{/other_user}","gists_url":"https://api.github.com/users/zdg2102/gists{/gist_id}","starred_url":"https://api.github.com/users/zdg2102/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zdg2102/subscriptions","organizations_url":"https://api.github.com/users/zdg2102/orgs","repos_url":"https://api.github.com/users/zdg2102/repos","events_url":"https://api.github.com/users/zdg2102/events{/privacy}","received_events_url":"https://api.github.com/users/zdg2102/received_events","type":"User","site_admin":false},"body":"- Remove redundant column name strings\r\n- Update column types to include enums and fixed string lengths\r\n- Add additional relationship tables to avoid use of postgres-only ARRAY type\r\n\r\nThis is to prepare the declarative_base schema to be used to generate the initial alembic migration to create the DB tables","created_at":"2018-12-04T21:54:47Z","updated_at":"2018-12-05T16:46:44Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ef33991e4ce8e6f2fd1e6a29446de16033c19257","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/pulls/251/commits","review_comments_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/pulls/251/comments","review_comment_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/issues/251/comments","statuses_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/statuses/7ee8706a12f436887f9710b02387b166bb375a28","head":{"label":"Recidiviz:update_sa_schema","ref":"update_sa_schema","sha":"7ee8706a12f436887f9710b02387b166bb375a28","user":{"login":"Recidiviz","id":35868122,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM1ODY4MTIy","avatar_url":"https://avatars2.githubusercontent.com/u/35868122?v=4","gravatar_id":"","url":"https://api.github.com/users/Recidiviz","html_url":"https://github.com/Recidiviz","followers_url":"https://api.github.com/users/Recidiviz/followers","following_url":"https://api.github.com/users/Recidiviz/following{/other_user}","gists_url":"https://api.github.com/users/Recidiviz/gists{/gist_id}","starred_url":"https://api.github.com/users/Recidiviz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Recidiviz/subscriptions","organizations_url":"https://api.github.com/users/Recidiviz/orgs","repos_url":"https://api.github.com/users/Recidiviz/repos","events_url":"https://api.github.com/users/Recidiviz/events{/privacy}","received_events_url":"https://api.github.com/users/Recidiviz/received_events","type":"Organization","site_admin":false},"repo":{"id":108306686,"node_id":"MDEwOlJlcG9zaXRvcnkxMDgzMDY2ODY=","name":"recidiviz-data","full_name":"Recidiviz/recidiviz-data","private":false,"owner":{"login":"Recidiviz","id":35868122,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM1ODY4MTIy","avatar_url":"https://avatars2.githubusercontent.com/u/35868122?v=4","gravatar_id":"","url":"https://api.github.com/users/Recidiviz","html_url":"https://github.com/Recidiviz","followers_url":"https://api.github.com/users/Recidiviz/followers","following_url":"https://api.github.com/users/Recidiviz/following{/other_user}","gists_url":"https://api.github.com/users/Recidiviz/gists{/gist_id}","starred_url":"https://api.github.com/users/Recidiviz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Recidiviz/subscriptions","organizations_url":"https://api.github.com/users/Recidiviz/orgs","repos_url":"https://api.github.com/users/Recidiviz/repos","events_url":"https://api.github.com/users/Recidiviz/events{/privacy}","received_events_url":"https://api.github.com/users/Recidiviz/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/Recidiviz/recidiviz-data","description":"Ingesting prison and jail records from various data sources and calculating criminal justice metrics","fork":false,"url":"https://api.github.com/repos/Recidiviz/recidiviz-data","forks_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/forks","keys_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/teams","hooks_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/hooks","issue_events_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/issues/events{/number}","events_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/events","assignees_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/assignees{/user}","branches_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/branches{/branch}","tags_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/tags","blobs_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/git/refs{/sha}","trees_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/statuses/{sha}","languages_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/languages","stargazers_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/stargazers","contributors_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/contributors","subscribers_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/subscribers","subscription_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/subscription","commits_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/commits{/sha}","git_commits_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/git/commits{/sha}","comments_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/comments{/number}","issue_comment_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/issues/comments{/number}","contents_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/contents/{+path}","compare_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/merges","archive_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/downloads","issues_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/issues{/number}","pulls_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/pulls{/number}","milestones_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/milestones{/number}","notifications_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/labels{/name}","releases_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/releases{/id}","deployments_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/deployments","created_at":"2017-10-25T18:04:59Z","updated_at":"2018-12-04T22:00:42Z","pushed_at":"2018-12-05T15:25:46Z","git_url":"git://github.com/Recidiviz/recidiviz-data.git","ssh_url":"git@github.com:Recidiviz/recidiviz-data.git","clone_url":"https://github.com/Recidiviz/recidiviz-data.git","svn_url":"https://github.com/Recidiviz/recidiviz-data","homepage":"","size":4782,"stargazers_count":6,"watchers_count":6,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":7,"mirror_url":null,"archived":false,"open_issues_count":72,"license":{"key":"gpl-3.0","name":"GNU General Public License v3.0","spdx_id":"GPL-3.0","url":"https://api.github.com/licenses/gpl-3.0","node_id":"MDc6TGljZW5zZTk="},"forks":7,"open_issues":72,"watchers":6,"default_branch":"master"}},"base":{"label":"Recidiviz:create_alembic_environment","ref":"create_alembic_environment","sha":"0ed51dcbfade91fb5aab586616c3ac9180fa63c7","user":{"login":"Recidiviz","id":35868122,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM1ODY4MTIy","avatar_url":"https://avatars2.githubusercontent.com/u/35868122?v=4","gravatar_id":"","url":"https://api.github.com/users/Recidiviz","html_url":"https://github.com/Recidiviz","followers_url":"https://api.github.com/users/Recidiviz/followers","following_url":"https://api.github.com/users/Recidiviz/following{/other_user}","gists_url":"https://api.github.com/users/Recidiviz/gists{/gist_id}","starred_url":"https://api.github.com/users/Recidiviz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Recidiviz/subscriptions","organizations_url":"https://api.github.com/users/Recidiviz/orgs","repos_url":"https://api.github.com/users/Recidiviz/repos","events_url":"https://api.github.com/users/Recidiviz/events{/privacy}","received_events_url":"https://api.github.com/users/Recidiviz/received_events","type":"Organization","site_admin":false},"repo":{"id":108306686,"node_id":"MDEwOlJlcG9zaXRvcnkxMDgzMDY2ODY=","name":"recidiviz-data","full_name":"Recidiviz/recidiviz-data","private":false,"owner":{"login":"Recidiviz","id":35868122,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM1ODY4MTIy","avatar_url":"https://avatars2.githubusercontent.com/u/35868122?v=4","gravatar_id":"","url":"https://api.github.com/users/Recidiviz","html_url":"https://github.com/Recidiviz","followers_url":"https://api.github.com/users/Recidiviz/followers","following_url":"https://api.github.com/users/Recidiviz/following{/other_user}","gists_url":"https://api.github.com/users/Recidiviz/gists{/gist_id}","starred_url":"https://api.github.com/users/Recidiviz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Recidiviz/subscriptions","organizations_url":"https://api.github.com/users/Recidiviz/orgs","repos_url":"https://api.github.com/users/Recidiviz/repos","events_url":"https://api.github.com/users/Recidiviz/events{/privacy}","received_events_url":"https://api.github.com/users/Recidiviz/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/Recidiviz/recidiviz-data","description":"Ingesting prison and jail records from various data sources and calculating criminal justice metrics","fork":false,"url":"https://api.github.com/repos/Recidiviz/recidiviz-data","forks_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/forks","keys_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/teams","hooks_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/hooks","issue_events_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/issues/events{/number}","events_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/events","assignees_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/assignees{/user}","branches_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/branches{/branch}","tags_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/tags","blobs_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/git/refs{/sha}","trees_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/statuses/{sha}","languages_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/languages","stargazers_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/stargazers","contributors_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/contributors","subscribers_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/subscribers","subscription_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/subscription","commits_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/commits{/sha}","git_commits_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/git/commits{/sha}","comments_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/comments{/number}","issue_comment_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/issues/comments{/number}","contents_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/contents/{+path}","compare_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/merges","archive_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/downloads","issues_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/issues{/number}","pulls_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/pulls{/number}","milestones_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/milestones{/number}","notifications_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/labels{/name}","releases_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/releases{/id}","deployments_url":"https://api.github.com/repos/Recidiviz/recidiviz-data/deployments","created_at":"2017-10-25T18:04:59Z","updated_at":"2018-12-04T22:00:42Z","pushed_at":"2018-12-05T15:25:46Z","git_url":"git://github.com/Recidiviz/recidiviz-data.git","ssh_url":"git@github.com:Recidiviz/recidiviz-data.git","clone_url":"https://github.com/Recidiviz/recidiviz-data.git","svn_url":"https://github.com/Recidiviz/recidiviz-data","homepage":"","size":4782,"stargazers_count":6,"watchers_count":6,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":7,"mirror_url":null,"archived":false,"open_issues_count":72,"license":{"key":"gpl-3.0","name":"GNU General Public License v3.0","spdx_id":"GPL-3.0","url":"https://api.github.com/licenses/gpl-3.0","node_id":"MDc6TGljZW5zZTk="},"forks":7,"open_issues":72,"watchers":6,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Recidiviz/recidiviz-data/pulls/251"},"html":{"href":"https://github.com/Recidiviz/recidiviz-data/pull/251"},"issue":{"href":"https://api.github.com/repos/Recidiviz/recidiviz-data/issues/251"},"comments":{"href":"https://api.github.com/repos/Recidiviz/recidiviz-data/issues/251/comments"},"review_comments":{"href":"https://api.github.com/repos/Recidiviz/recidiviz-data/pulls/251/comments"},"review_comment":{"href":"https://api.github.com/repos/Recidiviz/recidiviz-data/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Recidiviz/recidiviz-data/pulls/251/commits"},"statuses":{"href":"https://api.github.com/repos/Recidiviz/recidiviz-data/statuses/7ee8706a12f436887f9710b02387b166bb375a28"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"jessex"}}