def match_holds( *, db_booking: entities.Booking, ingested_booking: entities.Booking): """ Attempts to match all holds on the |ingested_booking| with holds on the |db_booking|. For any ingested hold, if a matching hold exists on |db_booking|, the primary key is updated on the ingested hold. All db holds that are not matched to an ingested hold are marked dropped and added to the |ingested_booking|. """ matched_holds_by_db_id: Dict[int, entities.Hold] = {} for ingested_hold in ingested_booking.holds: db_hold = cast(entities.Hold, get_only_match( ingested_hold, db_booking.holds, is_hold_match)) if db_hold: logging.debug( 'Successfully matched to hold with ID %s', db_hold.hold_id) # If the match was previously matched to a different database # charge, raise an error. if db_hold.hold_id in matched_holds_by_db_id: matches = [ingested_hold, matched_holds_by_db_id[db_hold.hold_id]] raise MatchedMultipleIngestedEntitiesError(db_hold, matches) ingested_hold.hold_id = db_hold.hold_id matched_holds_by_db_id[cast(int, db_hold.hold_id)] = ingested_hold dropped_holds = [] for db_hold in db_booking.holds: if db_hold.hold_id not in matched_holds_by_db_id: _drop_hold(db_hold) dropped_holds.append(db_hold) ingested_booking.holds.extend(dropped_holds)
def match_person( *, ingested_person: entities.Person, db_people: List[entities.Person], orphaned_entities: List[Entity], matched_people_by_db_id: Dict[int, entities.Person]) -> None: """ Finds the best match for the provided |ingested_person| from the provided |db_people|. If a match exists, the primary key is added onto the |ingested_person| and then we attempt to match all children entities. """ db_person = cast(entities.Person, get_best_match(ingested_person, db_people, county_matching_utils.is_person_match, matched_people_by_db_id.keys())) if db_person: person_id = db_person.get_id() logging.debug('Successfully matched to person with ID %s', person_id) # If the match was previously matched to a different database # person, raise an error. if person_id in matched_people_by_db_id: matches = [ingested_person, matched_people_by_db_id[person_id]] raise MatchedMultipleIngestedEntitiesError(db_person, matches) ingested_person.set_id(person_id) matched_people_by_db_id[cast(int, person_id)] = ingested_person match_bookings(db_person=db_person, ingested_person=ingested_person, orphaned_entities=orphaned_entities)
def match_bookings(*, db_person: entities.Person, ingested_person: entities.Person, orphaned_entities: List[Entity]): """ Attempts to match all bookings on the |ingested_person| with bookings on the |db_person|. For any ingested booking, if a matching booking exists on |db_person|, the primary key is updated on the ingested booking and we attempt to match all children entities. """ matched_bookings_by_db_id: Dict[int, entities.Booking] = {} for ingested_booking in ingested_person.bookings: db_booking: entities.Booking = \ cast(entities.Booking, get_only_match(ingested_booking, db_person.bookings, is_booking_match)) if db_booking: logging.debug('Successfully matched to booking with ID %s', db_booking.booking_id) # If the match was previously matched to a different database # booking, raise an error. if db_booking.booking_id in matched_bookings_by_db_id: matches = [ ingested_booking, matched_bookings_by_db_id[db_booking.booking_id] ] raise MatchedMultipleIngestedEntitiesError(db_booking, matches) matched_bookings_by_db_id[cast( int, db_booking.booking_id)] = ingested_booking ingested_booking.booking_id = db_booking.booking_id # Since db_booking exists, it must already have a first_seen_time, # which means that value should be used rather than any value # provided on the ingested_booking. ingested_booking.first_seen_time = db_booking.first_seen_time if (db_booking.admission_date_inferred and ingested_booking.admission_date_inferred): ingested_booking.admission_date = db_booking.admission_date ingested_booking.admission_date_inferred = True match_arrest(db_booking=db_booking, ingested_booking=ingested_booking) match_holds(db_booking=db_booking, ingested_booking=ingested_booking) match_charges(db_booking=db_booking, ingested_booking=ingested_booking) match_bonds(db_booking=db_booking, ingested_booking=ingested_booking, orphaned_entities=orphaned_entities) match_sentences(db_booking=db_booking, ingested_booking=ingested_booking, orphaned_entities=orphaned_entities) for db_booking in db_person.bookings: if db_booking.booking_id not in matched_bookings_by_db_id: ingested_person.bookings.append(db_booking)
def _add_match_to_matched_entities_cache( *, db_entity_match: Entity, ingested_entity: Entity, matched_entities_by_db_ids: Dict[int, Entity]): """Records a new ingested_entity/db_entity match. If the DB entity has already been matched to a different ingested_entity, it raises an error. """ matched_db_id = db_entity_match.get_id() if matched_db_id in matched_entities_by_db_ids: if ingested_entity != matched_entities_by_db_ids[matched_db_id]: matches = [ ingested_entity, matched_entities_by_db_ids[matched_db_id] ] # It's ok for a DB object to match multiple ingested placeholders. if is_placeholder(matches[0]) and is_placeholder(matches[1]): return raise MatchedMultipleIngestedEntitiesError(db_entity_match, matches) else: matched_entities_by_db_ids[matched_db_id] = ingested_entity