def merge_building( snapshot, b1, b2, can_attrs, conf, default=None, match_type=None ): """Set attributes on our Canonical model, saving differences. :param snapshot: BuildingSnapshot model inst. :param b1: BuildingSnapshot model inst. Left parent. :param b2: BuildingSnapshot model inst. Right parent. :param can_attrs: dict of dicts, {'attr_name': {'dataset1': 'value'...}}. :param default: (optional), which dataset's value to default to. :rtype BuildingSnapshot inst(``snapshot``), updated. """ default = default or b1 match_type = match_type or models.SYSTEM_MATCH for attr in can_attrs: # Do we have any differences between these fields? attr_values = list(set([ value for value in can_attrs[attr].values() if value ])) attr_value = None # Two, differing values are set. if len(attr_values) > 1: # If we have more than one value for this field, # save each of the field options in the DB, # but opt for the default when there is a difference. save_variant(snapshot, attr, can_attrs[attr]) attr_source = default attr_value = can_attrs[attr][default] # No values are set elif len(attr_values) < 1: attr_value = None attr_source = None # There is only one value set. else: attr_value = attr_values.pop() # Get the correct key from the sub dictionary to indicate # the source of a field value. attr_source = get_attr_source(can_attrs[attr], attr_value) if callable(attr): # This callable will be responsible for setting # the attribute value, not just returning it. attr(snapshot, default) else: setattr(snapshot, attr, attr_value) setattr(snapshot, '{0}_source'.format(attr), attr_source) snapshot.extra_data, snapshot.extra_data_sources = merge_extra_data( b1, b2, default=default ) snapshot.match_type = match_type snapshot.source_type = models.COMPOSITE_BS canonical_building = models.get_or_create_canonical(b1, b2) snapshot.canonical_building = canonical_building snapshot.confidence = conf snapshot.save() canonical_building.canonical_snapshot = snapshot canonical_building.save() b1.children.add(snapshot) b2.children.add(snapshot) return snapshot
def merge_building(snapshot, b1, b2, can_attrs, conf, default=None, match_type=None): """Set attributes on our Canonical model, saving differences. :param snapshot: BuildingSnapshot model inst. :param b1: BuildingSnapshot model inst. Left parent. :param b2: BuildingSnapshot model inst. Right parent. :param can_attrs: dict of dicts, {'attr_name': {'dataset1': 'value'...}}. :param default: (optional), which dataset's value to default to. :rtype BuildingSnapshot inst(``snapshot``), updated. """ default = default or b1 match_type = match_type or models.SYSTEM_MATCH changes = [] for attr in can_attrs: # Do we have any differences between these fields? attr_values = list( set([value for value in can_attrs[attr].values() if value])) attr_value = None # Two, differing values are set. if len(attr_values) > 1: # If we have more than one value for this field, # save each of the field options in the DB, # but opt for the default when there is a difference. save_variant(snapshot, attr, can_attrs[attr]) attr_source = default attr_value = can_attrs[attr][default] if attr_values[0] != attr_values[1]: changes.append({ "field": attr, "from": attr_values[0], "to": attr_values[1] }) # No values are set elif len(attr_values) < 1: attr_value = None attr_source = None # There is only one value set. else: attr_value = attr_values.pop() # Get the correct key from the sub dictionary to indicate # the source of a field value. attr_source = get_attr_source(can_attrs[attr], attr_value) if callable(attr): # This callable will be responsible for setting # the attribute value, not just returning it. attr(snapshot, default) else: setattr(snapshot, attr, attr_value) setattr(snapshot, '{0}_source'.format(attr), attr_source) snapshot.extra_data, snapshot.extra_data_sources = merge_extra_data( b1, b2, default=default) snapshot.match_type = match_type snapshot.source_type = models.COMPOSITE_BS canonical_building = models.get_or_create_canonical(b1, b2) snapshot.canonical_building = canonical_building snapshot.confidence = conf snapshot.save() canonical_building.canonical_snapshot = snapshot canonical_building.save() b1.children.add(snapshot) b2.children.add(snapshot) return snapshot, changes