def test_persistLocally(self): # Arrange with patch('os.getenv', Mock(return_value='local')) \ and patch.dict('os.environ', {'PERSIST_LOCALLY': 'true'}): ingest_info = IngestInfo() ingest_info.people.add(full_name=FULL_NAME_1) # Act persistence.write(ingest_info, DEFAULT_METADATA) result = county_dao.read_people( SessionFactory.for_schema_base(JailsBase)) # Assert assert len(result) == 1 assert result[0].full_name == _format_full_name(FULL_NAME_1)
def test_ingest_file_metadata_split_file_no_file_name_raises(self): session = SessionFactory.for_schema_base(OperationsBase) ingest_file_metadata = schema.DirectIngestIngestFileMetadata( region_code="us_xx_yyyy", file_tag="file_tag", is_invalidated=False, is_file_split=True, job_creation_time=datetime.datetime.now(), datetimes_contained_lower_bound_exclusive=None, datetimes_contained_upper_bound_inclusive=datetime.datetime( 2020, 5, 11), ) session.add(ingest_file_metadata) with self.assertRaises(IntegrityError): session.commit()
def test_add_person_update_with_new_id(self) -> None: # Arrange arrange_session = SessionFactory.for_schema_base(StateBase) db_external_id = generate_external_id(state_code=self.state_code, external_id=EXTERNAL_ID_1, id_type=ID_TYPE_1) db_person = generate_person(state_code=self.state_code, external_ids=[db_external_id]) arrange_session.add(db_person) arrange_session.commit() db_external_id_2 = generate_external_id(state_code=self.state_code, external_id=EXTERNAL_ID_2, id_type=ID_TYPE_1) # Act session = SessionFactory.for_schema_base(StateBase) result = session.query(schema.StatePerson).all() person_to_update = one(result) person_to_update.external_ids.append(db_external_id_2) session.flush() output_people = [person_to_update] errors = validate_invariants(session, self.system_level, self.state_code, output_people) # Assert self.assertEqual(1, errors) session.rollback()
def mark_ingest_view_exported( self, metadata_entity: DirectIngestIngestFileMetadata) -> None: session = SessionFactory.for_schema_base(OperationsBase) try: metadata = dao.get_file_metadata_row( session, GcsfsDirectIngestFileType.INGEST_VIEW, metadata_entity.file_id) metadata.export_time = datetime.datetime.utcnow() session.commit() except Exception as e: session.rollback() raise e finally: session.close()
def test_twoDifferentPeople_persistsNone(self): # Arrange ingest_info = IngestInfo() ingest_info.people.add(person_id='1', full_name=FULL_NAME_1) ingest_info.people.add(person_id='2', full_name=FULL_NAME_2, gender='X') # Act self.assertFalse(persistence.write(ingest_info, DEFAULT_METADATA)) result = county_dao.read_people( SessionFactory.for_schema_base(JailsBase)) # Assert assert not result
def test_readPersonMultipleIdsMatch(self) -> None: # Arrange person = schema.StatePerson(person_id=1, state_code=_STATE_CODE) person_external_id = schema.StatePersonExternalId( person_external_id_id=1, external_id=_EXTERNAL_ID, id_type=external_id_types.US_ND_SID, state_code=_STATE_CODE, person=person, ) person_external_id2 = schema.StatePersonExternalId( person_external_id_id=2, external_id=_EXTERNAL_ID2, id_type=external_id_types.US_ND_SID, state_code=_STATE_CODE, person=person, ) person.external_ids = [person_external_id, person_external_id2] session = SessionFactory.for_schema_base(StateBase) session.add(person) session.commit() ingested_person = entities.StatePerson.new_with_defaults( state_code=_STATE_CODE) ingested_person.external_ids = [ entities.StatePersonExternalId.new_with_defaults( external_id=_EXTERNAL_ID, id_type=external_id_types.US_ND_SID, state_code=_STATE_CODE, ), entities.StatePersonExternalId.new_with_defaults( external_id=_EXTERNAL_ID2, id_type=external_id_types.US_ND_SID, state_code=_STATE_CODE, ), ] # Act people = dao.read_people_by_external_ids(session, _REGION, [ingested_person]) # Assert expected_people = [person] self.assertCountEqual(people, expected_people)
def test_matchPeople_twoMatchingPeople_PicksMostSimilar(self): # Arrange schema_person = schema.Person( person_id=_PERSON_ID, external_id=_EXTERNAL_ID, jurisdiction_id=_JURISDICTION_ID, full_name=_FULL_NAME, birthdate=_DATE, region=_REGION, gender=Gender.MALE.value, ) schema_person_mismatch = copy.deepcopy(schema_person) schema_person_mismatch.person_id = _PERSON_ID_ANOTHER schema_person_mismatch.gender = Gender.FEMALE.value session = SessionFactory.for_schema_base(JailsBase) session.add(schema_person) session.add(schema_person_mismatch) session.commit() ingested_person = attr.evolve( converter.convert_schema_object_to_entity(schema_person), person_id=None ) expected_person = attr.evolve( ingested_person, person_id=schema_person.person_id ) # Act matched_entities = entity_matching.match(session, _REGION, [ingested_person]) # Assert both schema objects are matches, but we select the most # similar one. self.assertTrue( county_matching_utils.is_person_match( db_entity=schema_person, ingested_entity=ingested_person ) ) self.assertTrue( county_matching_utils.is_person_match( db_entity=schema_person_mismatch, ingested_entity=ingested_person ) ) self.assertEqual(matched_entities.error_count, 0) self.assertEqual(len(matched_entities.orphaned_entities), 0) self.assertEqual(ingested_person, expected_person)
def test_twoDifferentPeople_persistsBoth(self): # Arrange ingest_info = IngestInfo() ingest_info.people.add(person_id='1_GENERATE', full_name=FULL_NAME_1) ingest_info.people.add(person_id='2_GENERATE', full_name=FULL_NAME_2) # Act persistence.write(ingest_info, DEFAULT_METADATA) result = county_dao.read_people( SessionFactory.for_schema_base(JailsBase)) # Assert assert len(result) == 2 assert result[0].full_name == _format_full_name(FULL_NAME_2) assert result[1].full_name == _format_full_name(FULL_NAME_1)
def test_raw_file_metadata(self): session = SessionFactory.for_schema_base(OperationsBase) raw_metadata = schema.DirectIngestRawFileMetadata( region_code='us_xx_yyyy', file_tag='file_tag', discovery_time=datetime.datetime.now(), normalized_file_name='foo.txt', datetimes_contained_upper_bound_inclusive=datetime.datetime( 2019, 10, 11), ) session.add(raw_metadata) session.commit() result_metadata = one( session.query(schema.DirectIngestRawFileMetadata).all()) self.assertEqual(result_metadata, raw_metadata) self.assertIsNotNone(result_metadata.file_id)
def test_readPersons_unexpectedRoot_raises(self) -> None: ingested_supervision_sentence = schema.StateSupervisionSentence( external_id=_EXTERNAL_ID) ingested_sentence_group = schema.StateSentenceGroup( supervision_sentences=[ingested_supervision_sentence]) ingested_person = schema.StatePerson( sentence_groups=[ingested_sentence_group]) with pytest.raises(ValueError): session = SessionFactory.for_schema_base(StateBase) read_persons_by_root_entity_cls( session, "us_nd", [ingested_person], allowed_root_entity_classes=[schema.StateSentenceGroup], )
def infer_release_on_open_bookings(region_code: str, last_ingest_time: datetime.datetime, custody_status: CustodyStatus) -> None: """ Look up all open bookings whose last_seen_time is earlier than the provided last_ingest_time in the provided region, update those bookings to have an inferred release date equal to the provided last_ingest_time. Args: region_code: the region_code last_ingest_time: The last time complete data was ingested for this region. In the normal ingest pipeline, this is the last start time of a background scrape for the region. custody_status: The custody status to be marked on the found open bookings. Defaults to INFERRED_RELEASE """ session = SessionFactory.for_schema_base(JailsBase) try: logging.info("Reading all bookings that happened before [%s]", last_ingest_time) people = county_dao.read_people_with_open_bookings_scraped_before_time( session, region_code, last_ingest_time) logging.info( "Found [%s] people with bookings that will be inferred released", len(people), ) for person in people: persistence_utils.remove_pii_for_person(person) _infer_release_date_for_bookings(person.bookings, last_ingest_time, custody_status) db_people = converter.convert_entity_people_to_schema_people(people) database.write_people( session, db_people, IngestMetadata(region=region_code, jurisdiction_id="", ingest_time=last_ingest_time), ) session.commit() except Exception: session.rollback() raise finally: session.close()
def testWriteDf_doesNotOverrideMatchingColumnNames(self): # Arrange subject = pd.DataFrame({ 'county_name': ['Alachua', 'Baker', 'Bay', 'Bradford', 'Brevard'], 'county_population': [257062, 26965, 176016, 27440, 568919], 'average_daily_population': [799, 478, 1015, 141, 1547], 'date_reported': [ pd.NaT, pd.NaT, datetime.datetime(year=2017, month=9, day=1), pd.NaT, pd.NaT ], 'fips': ['00000', '00001', '00002', '00003', '00004'], 'report_date': 5 * [DATE_SCRAPED], 'aggregation_window': 5 * [enum_strings.monthly_granularity], 'report_frequency': 5 * [enum_strings.monthly_granularity] }) dao.write_df(FlCountyAggregate, subject) subject = pd.DataFrame({ 'facility_name': ['One', 'Two', 'Three', 'Four', 'Five'], 'average_daily_population': [13, 14, 15, 16, 17], 'number_felony_pretrial': [23, 24, 25, 26, 27], 'number_misdemeanor_pretrial': 5 * [pd.NaT], 'fips': ['10000', '10111', '10222', '10333', '10444'], 'report_date': 5 * [DATE_SCRAPED], 'aggregation_window': 5 * [enum_strings.monthly_granularity], 'report_frequency': 5 * [enum_strings.monthly_granularity] }) # Act dao.write_df(FlFacilityAggregate, subject) # Assert query = SessionFactory.for_schema_base(JailsBase) \ .query(FlCountyAggregate) \ .filter(FlCountyAggregate.county_name == 'Bay') result = one(query.all()) fips_not_overridden_by_facility_table = '00002' self.assertEqual(result.county_name, 'Bay') self.assertEqual(result.fips, fips_not_overridden_by_facility_table)
def test_ingest_view_file_progression_two_files_same_tag(self) -> None: args = GcsfsIngestViewExportArgs( ingest_view_name="file_tag", upper_bound_datetime_prev=None, upper_bound_datetime_to_export=datetime.datetime( 2015, 1, 2, 2, 2, 2, 2), ) ingest_view_unprocessed_path_1 = self._make_unprocessed_path( "bucket/file_tag.csv", GcsfsDirectIngestFileType.INGEST_VIEW, dt=datetime.datetime(2015, 1, 2, 2, 2, 2, 2), ) self.run_ingest_view_file_progression(args, self.metadata_manager, ingest_view_unprocessed_path_1) args = GcsfsIngestViewExportArgs( ingest_view_name="file_tag", upper_bound_datetime_prev=datetime.datetime( 2015, 1, 2, 2, 2, 2, 2), upper_bound_datetime_to_export=datetime.datetime( 2015, 1, 3, 3, 3, 3, 3), ) ingest_view_unprocessed_path_2 = self._make_unprocessed_path( "bucket/file_tag.csv", GcsfsDirectIngestFileType.INGEST_VIEW, dt=datetime.datetime(2015, 1, 3, 3, 3, 3, 3), ) self.run_ingest_view_file_progression(args, self.metadata_manager, ingest_view_unprocessed_path_2) session = SessionFactory.for_schema_base(OperationsBase) results = session.query(schema.DirectIngestIngestFileMetadata).all() self.assertEqual( { ingest_view_unprocessed_path_1.file_name, ingest_view_unprocessed_path_2.file_name, }, {r.normalized_file_name for r in results}, ) for r in results: self.assertTrue(r.export_time) self.assertTrue(r.processed_time)
def test_ingest_file_metadata(self): session = SessionFactory.for_schema_base(OperationsBase) ingest_file_metadata = schema.DirectIngestIngestFileMetadata( region_code='us_xx_yyyy', file_tag='file_tag', is_invalidated=False, is_file_split=False, job_creation_time=datetime.datetime.now(), datetimes_contained_lower_bound_exclusive=None, datetimes_contained_upper_bound_inclusive=datetime.datetime( 2020, 5, 11)) session.add(ingest_file_metadata) session.commit() result_metadata = one( session.query(schema.DirectIngestIngestFileMetadata).all()) self.assertEqual(result_metadata, ingest_file_metadata) self.assertIsNotNone(result_metadata.file_id)
def test_scraper_success(self, mock_get_region, mock_client): mock_get_region.return_value = _mock_region() session = sessions.ScrapeSession.new( key=None, region=_REGION_CODE, scrape_type=constants.ScrapeType.BACKGROUND, phase=scrape_phase.ScrapePhase.RELEASE) sessions.update_phase(session, scrape_phase.ScrapePhase.DONE) query = SessionFactory.for_schema_base(JailsBase).query(ScraperSuccess) result = one(query.all()) region = regions.get_region(_REGION_CODE) self.assertEqual(result.jid, region.jurisdiction_id) self.assertEqual(result.date, _TODAY)
def test_readPersonsByRootEntityCls(self): schema_person_with_root_entity = schema.StatePerson(person_id=1) schema_sentence_group = schema.StateSentenceGroup( sentence_group_id=_ID, external_id=_EXTERNAL_ID, status=StateSentenceStatus.PRESENT_WITHOUT_INFO.value, state_code='US_ND') schema_sentence_group_2 = schema.StateSentenceGroup( sentence_group_id=_ID_2, external_id=_EXTERNAL_ID_2, status=StateSentenceStatus.PRESENT_WITHOUT_INFO.value, state_code='US_ND') schema_person_with_root_entity.sentence_groups = [ schema_sentence_group, schema_sentence_group_2 ] placeholder_schema_person = schema.StatePerson(person_id=_ID_2) schema_person_other_state = schema.StatePerson(person_id=_ID_3) schema_external_id_other_state = schema.StatePersonExternalId( person_external_id_id=_ID_2, external_id=_ID, id_type=_ID_TYPE, state_code=_STATE_CODE) schema_person_other_state.external_ids = [ schema_external_id_other_state ] session = SessionFactory.for_schema_base(StateBase) session.add(schema_person_with_root_entity) session.add(placeholder_schema_person) session.add(schema_person_other_state) session.commit() ingested_sentence_group = schema.StateSentenceGroup( state_code='us_nd', external_id=_EXTERNAL_ID) ingested_person = schema.StatePerson( sentence_groups=[ingested_sentence_group]) expected_people = [ schema_person_with_root_entity, placeholder_schema_person ] people = read_persons_by_root_entity_cls( session, 'us_nd', [ingested_person], allowed_root_entity_classes=[schema.StateSentenceGroup]) self.assert_schema_object_lists_equal(expected_people, people)
def testWriteDf_OverlappingData_WritesNewAndIgnoresDuplicateRows(self): # Arrange initial_df = pd.DataFrame({ 'county_name': ['Alachua', 'Baker', 'Bay', 'Bradford', 'Brevard'], 'county_population': [257062, 26965, 176016, 27440, 568919], 'average_daily_population': [799, 478, 1015, 141, 1547], 'date_reported': [ pd.NaT, pd.NaT, datetime.datetime(year=2017, month=9, day=1), pd.NaT, pd.NaT ], 'fips': ['00000', '00001', '00002', '00003', '00004'], 'report_date': 5 * [DATE_SCRAPED], 'aggregation_window': 5 * [enum_strings.monthly_granularity], 'report_frequency': 5 * [enum_strings.monthly_granularity] }) dao.write_df(FlCountyAggregate, initial_df) subject = pd.DataFrame({ 'county_name': ['Alachua', 'NewCounty', 'Baker'], 'county_population': [0, 1000000000, 0], 'average_daily_population': [0, 50, 0], 'date_reported': [pd.NaT, pd.NaT, pd.NaT], 'fips': ['00000', '01000', '00002'], 'report_date': 3 * [DATE_SCRAPED], 'aggregation_window': 3 * [enum_strings.monthly_granularity], 'report_frequency': 3 * [enum_strings.monthly_granularity] }) # Act dao.write_df(FlCountyAggregate, subject) # Assert query = SessionFactory.for_schema_base(JailsBase).query( func.sum(FlCountyAggregate.county_population)) result = one(one(query.all())) # This sum includes intial_df + NewCounty and ignores other changes in # the subject (eg. county_population = 0 for 'Alachua') expected_sum_county_populations = 1001056402 self.assertEqual(result, expected_sum_county_populations)
def test_readPeople_byFullName(self): # Arrange person = schema.StatePerson(person_id=8, full_name=_FULL_NAME) person_different_name = schema.StatePerson(person_id=9, full_name='diff_name') session = SessionFactory.for_schema_base(StateBase) session.add(person) session.add(person_different_name) session.commit() # Act people = dao.read_people(session, full_name=_FULL_NAME, birthdate=None) # Assert expected_people = [person] self.assertCountEqual(people, expected_people)
def test_readPeople_byBirthdate(self): # Arrange person = schema.StatePerson(person_id=8, birthdate=_BIRTHDATE) person_different_birthdate = schema.StatePerson( person_id=9, birthdate=datetime.date(year=2002, month=1, day=2)) session = SessionFactory.for_schema_base(StateBase) session.add(person) session.add(person_different_birthdate) session.commit() # Act people = dao.read_people(session, full_name=None, birthdate=_BIRTHDATE) # Assert expected_people = [person] self.assertCountEqual(people, expected_people)
def store_scraper_success(scraper_success: ScraperSuccessModel, jurisdiction_id: str) -> bool: """Store a scraper success event""" jurisdiction_id = validate_jid(jurisdiction_id) ss = ScraperSuccessEntry( jid=jurisdiction_id, date=scraper_success.date, ) session = SessionFactory.for_schema_base( schema_base_for_system_level(SystemLevel.COUNTY)) session.add(ss) session.commit() return True
def testWrite_CorrectlyReadsHernandoCounty(self): # Act for table, df in self.parsed_pdf.items(): dao.write_df(table, df) # Assert query = SessionFactory.for_schema_base(JailsBase) \ .query(FlCountyAggregate) \ .filter(FlCountyAggregate.county_name == 'Hernando') hernando_row = one(query.all()) self.assertEqual(hernando_row.county_name, 'Hernando') self.assertEqual(hernando_row.county_population, 179503) self.assertEqual(hernando_row.average_daily_population, 632) self.assertEqual(hernando_row.date_reported, datetime.date(year=2017, month=9, day=1))
def test_write_noPeople(self): # Arrange most_recent_scrape_time = (SCRAPER_START_DATETIME + timedelta(days=1)) metadata = IngestMetadata.new_with_defaults( region=REGION_1, jurisdiction_id=JURISDICTION_ID, ingest_time=most_recent_scrape_time) ingest_info = IngestInfo() # Act persistence.write(ingest_info, metadata) # Assert people = county_dao.read_people( SessionFactory.for_schema_base(JailsBase)) self.assertFalse(people)
def get_ingest_view_metadata_pending_export(self) -> List[DirectIngestIngestFileMetadata]: session = SessionFactory.for_schema_base(OperationsBase) try: results = dao.get_ingest_view_metadata_pending_export( session=session, region_code=self.region_code, ) metadata_entities = [self._ingest_file_schema_metadata_as_entity(metadata) for metadata in results] except Exception as e: session.rollback() raise e finally: session.close() return metadata_entities
def testWrite_SingleCountToday(self): params = { "jid": "01001001", "count": 311, } headers = {"X-Appengine-Cron": "test-cron"} response = self.client.get(f"/single_count?{urlencode(params)}", headers=headers) self.assertEqual(response.status_code, 200) # Assert query = SessionFactory.for_schema_base(JailsBase).query( SingleCountAggregate) result = one(query.all()) self.assertEqual(result.count, params["count"]) self.assertEqual(result.date, datetime.date.today())
def testWrite_SingleCountToday(self): params = { 'jid': '01001001', 'count': 311, } headers = {'X-Appengine-Cron': 'test-cron'} response = self.client.get(f'/single_count?{urlencode(params)}', headers=headers) self.assertEqual(response.status_code, 200) # Assert query = SessionFactory.for_schema_base(JailsBase).query( SingleCountAggregate) result = one(query.all()) self.assertEqual(result.count, params['count']) self.assertEqual(result.date, datetime.date.today())
def test_ingest_file_processed_time_no_discovery_time_raises(self): session = SessionFactory.for_schema_base(OperationsBase) ingest_file_metadata = schema.DirectIngestIngestFileMetadata( region_code='us_xx_yyyy', file_tag='file_tag', is_invalidated=False, job_creation_time=datetime.datetime.now(), datetimes_contained_lower_bound_exclusive=None, datetimes_contained_upper_bound_inclusive=datetime.datetime( 2020, 5, 11), export_time=datetime.datetime(2020, 5, 12), normalized_file_name='foo.txt', processed_time=datetime.datetime(2020, 5, 13), ) session.add(ingest_file_metadata) with self.assertRaises(IntegrityError): session.commit()
def test_readObjsWithExternalIdMatch(self): person_1 = schema.StatePerson(person_id=1) sentence_group_1 = schema.StateSentenceGroup( sentence_group_id=1, external_id=_EXTERNAL_ID, status=StateSentenceStatus.PRESENT_WITHOUT_INFO.value, state_code=_STATE_CODE, person=person_1) person_1.sentence_groups = [sentence_group_1] person_2 = schema.StatePerson(person_id=2) sentence_group_1_dup = schema.StateSentenceGroup( sentence_group_id=2, external_id=_EXTERNAL_ID, status=StateSentenceStatus.PRESENT_WITHOUT_INFO.value, state_code=_STATE_CODE, person=person_2) sentence_group_2 = schema.StateSentenceGroup( sentence_group_id=3, external_id=_EXTERNAL_ID2, status=StateSentenceStatus.PRESENT_WITHOUT_INFO.value, state_code=_STATE_CODE, person=person_2) placeholder_sentence_group = schema.StateSentenceGroup( sentence_group_id=4, status=StateSentenceStatus.PRESENT_WITHOUT_INFO.value, state_code=_STATE_CODE, person=person_2) person_2.sentence_groups = [ sentence_group_1_dup, sentence_group_2, placeholder_sentence_group ] session = SessionFactory.for_schema_base(StateBase) session.add(person_1) session.add(person_2) session.commit() # Act external_ids = dao.read_external_ids_of_cls_with_external_id_match( session, _STATE_CODE, schema.StateSentenceGroup) # Assert self.assertEqual(external_ids, [_EXTERNAL_ID])
def test_convert_single_node(self): parent = entities.Parent.new_with_defaults( parent_id=1234, full_name="Krusty the Clown", children=[]) converter = _TestSchemaEntityConverter() schema_parent = converter.convert(parent) session = SessionFactory.for_schema_base(TestBase) session.add(schema_parent) session.commit() parents = session.query(schema.Parent).all() self.assertEqual(len(parents), 1) children = session.query(schema.Child).all() self.assertEqual(len(children), 0) converted_parent = _TestSchemaEntityConverter().convert(one(parents)) self.assertEqual(parent, converted_parent)
def test_twoDifferentPeopleWithBooking_persistsNone(self): # Arrange ingest_info = IngestInfo() ingest_info.people.add(full_name=FULL_NAME_2) ingest_info.people.add(full_name=FULL_NAME_1, person_id=EXTERNAL_PERSON_ID, booking_ids=[EXTERNAL_BOOKING_ID]) ingest_info.bookings.add( booking_id=EXTERNAL_BOOKING_ID, custody_status='NO EXIST', ) # Act self.assertFalse(persistence.write(ingest_info, DEFAULT_METADATA)) result = county_dao.read_people( SessionFactory.for_schema_base(JailsBase)) # Assert assert not result
def test_readPeopleWithOpenBookings(self): admission_date = datetime.datetime(2018, 6, 20) release_date = datetime.date(2018, 7, 20) open_booking = Booking( custody_status=CustodyStatus.IN_CUSTODY.value, admission_date=admission_date, first_seen_time=admission_date, last_seen_time=admission_date) closed_booking = Booking( custody_status=CustodyStatus.RELEASED.value, admission_date=admission_date, release_date=release_date, first_seen_time=admission_date, last_seen_time=admission_date) person_no_match = Person(person_id=1, region=_REGION, jurisdiction_id=_JURISDICTION_ID, bookings=[deepcopy(open_booking)]) person_match_full_name = Person(person_id=2, region=_REGION, jurisdiction_id=_JURISDICTION_ID, bookings=[deepcopy(open_booking)], full_name=_FULL_NAME) person_no_open_bookings = Person(person_id=6, region=_REGION, jurisdiction_id=_JURISDICTION_ID, full_name=_FULL_NAME, bookings=[closed_booking]) session = SessionFactory.for_schema_base(JailsBase) session.add(person_no_match) session.add(person_no_open_bookings) session.add(person_match_full_name) session.commit() info = IngestInfo() info.create_person(full_name=_FULL_NAME, person_id=_EXTERNAL_ID) people = dao.read_people_with_open_bookings(session, _REGION, info.people) expected_people = [converter.convert_schema_object_to_entity(p) for p in [person_match_full_name]] self.assertCountEqual(people, expected_people)