Skip to content
Snippets Groups Projects

DRAFT: Improve the compare_entities function

Open Florian Spreckelsen requested to merge f-check-merge-entities into dev
3 files
+ 176
44
Compare changes
  • Side-by-side
  • Inline
Files
3
+ 32
5
@@ -178,7 +178,8 @@ def getCommitIn(folder):
@@ -178,7 +178,8 @@ def getCommitIn(folder):
return get_commit_in(folder)
return get_commit_in(folder)
def compare_entities(old_entity: Entity, new_entity: Entity, compare_referenced_records: bool = False):
def compare_entities(old_entity: Entity, new_entity: Entity,
 
compare_referenced_records: bool = False):
"""Compare two entites.
"""Compare two entites.
Return a tuple of dictionaries, the first index belongs to additional information for old
Return a tuple of dictionaries, the first index belongs to additional information for old
@@ -189,8 +190,9 @@ def compare_entities(old_entity: Entity, new_entity: Entity, compare_referenced_
@@ -189,8 +190,9 @@ def compare_entities(old_entity: Entity, new_entity: Entity, compare_referenced_
- Information about properties:
- Information about properties:
- Each property lists either an additional property or a property with a changed:
- Each property lists either an additional property or a property with a changed:
- datatype
- datatype
 
- unit
- importance or
- importance or
- value (not implemented yet)
- value
In case of changed information the value listed under the respective key shows the
In case of changed information the value listed under the respective key shows the
value that is stored in the respective entity.
value that is stored in the respective entity.
@@ -200,6 +202,9 @@ def compare_entities(old_entity: Entity, new_entity: Entity, compare_referenced_
@@ -200,6 +202,9 @@ def compare_entities(old_entity: Entity, new_entity: Entity, compare_referenced_
`compare_referenced_records = False` to prevent infinite recursion in case
`compare_referenced_records = False` to prevent infinite recursion in case
of circular references).
of circular references).
 
NOTE: This function does not work for abstract properties! I.e. it is not possible
 
to directly compare two entities that are of class caosdb.Property.
 
Parameters
Parameters
----------
----------
old_entity, new_entity : Entity
old_entity, new_entity : Entity
@@ -212,6 +217,12 @@ def compare_entities(old_entity: Entity, new_entity: Entity, compare_referenced_
@@ -212,6 +217,12 @@ def compare_entities(old_entity: Entity, new_entity: Entity, compare_referenced_
identical records are stored in different objects. Default is False.
identical records are stored in different objects. Default is False.
"""
"""
 
 
for entity in (old_entity, new_entity):
 
if isinstance(entity, Property):
 
raise NotImplementedError("The function compare_entities does not work for "
 
"comparing abstract properties.")
 
olddiff: Dict[str, Any] = {"properties": {}, "parents": []}
olddiff: Dict[str, Any] = {"properties": {}, "parents": []}
newdiff: Dict[str, Any] = {"properties": {}, "parents": []}
newdiff: Dict[str, Any] = {"properties": {}, "parents": []}
@@ -239,7 +250,7 @@ def compare_entities(old_entity: Entity, new_entity: Entity, compare_referenced_
@@ -239,7 +250,7 @@ def compare_entities(old_entity: Entity, new_entity: Entity, compare_referenced_
if not old_entity_attr_exists and not new_entity_attr_exists:
if not old_entity_attr_exists and not new_entity_attr_exists:
continue
continue
if ((old_entity_attr_exists ^ new_entity_attr_exists)
if ((old_entity_attr_exists != new_entity_attr_exists)
or (oldattr != newattr)):
or (oldattr != newattr)):
if old_entity_attr_exists:
if old_entity_attr_exists:
@@ -251,9 +262,21 @@ def compare_entities(old_entity: Entity, new_entity: Entity, compare_referenced_
@@ -251,9 +262,21 @@ def compare_entities(old_entity: Entity, new_entity: Entity, compare_referenced_
# properties
# properties
for prop in old_entity.properties:
for prop in old_entity.properties:
 
# Find the corresponding property in new_entity:
matching = [p for p in new_entity.properties if p.name == prop.name]
matching = [p for p in new_entity.properties if p.name == prop.name]
 
# This is needed for checking for multi properties in old_entity:
 
# TODO: is there a better way?
 
matching_old = [p for p in old_entity.properties if p.name == prop.name]
 
if len(matching_old) != 1:
 
raise NotImplementedError(
 
"Comparison not implemented for multi-properties.")
 
if len(matching) > 1:
 
raise NotImplementedError(
 
"Comparison not implemented for multi-properties.")
 
if len(matching) == 0:
if len(matching) == 0:
 
# There is no matching property in new_entity:
olddiff["properties"][prop.name] = {}
olddiff["properties"][prop.name] = {}
elif len(matching) == 1:
elif len(matching) == 1:
newdiff["properties"][prop.name] = {}
newdiff["properties"][prop.name] = {}
@@ -283,6 +306,7 @@ def compare_entities(old_entity: Entity, new_entity: Entity, compare_referenced_
@@ -283,6 +306,7 @@ def compare_entities(old_entity: Entity, new_entity: Entity, compare_referenced_
# scalar reference
# scalar reference
if isinstance(prop.value, Entity) and isinstance(matching[0].value, Entity):
if isinstance(prop.value, Entity) and isinstance(matching[0].value, Entity):
# explicitely not recursive to prevent infinite recursion
# explicitely not recursive to prevent infinite recursion
 
# TODO: why not use a recursion detection with a cache?
same_value = empty_diff(
same_value = empty_diff(
prop.value, matching[0].value, compare_referenced_records=False)
prop.value, matching[0].value, compare_referenced_records=False)
# list of references
# list of references
@@ -306,11 +330,14 @@ def compare_entities(old_entity: Entity, new_entity: Entity, compare_referenced_
@@ -306,11 +330,14 @@ def compare_entities(old_entity: Entity, new_entity: Entity, compare_referenced_
newdiff["properties"].pop(prop.name)
newdiff["properties"].pop(prop.name)
olddiff["properties"].pop(prop.name)
olddiff["properties"].pop(prop.name)
else:
# Check whether there are missing properties in old_entity, additionally
 
# check for multi-properties that are currently not supported:
 
for prop in new_entity.properties:
 
matching = [p for p in new_entity.properties if p.name == prop.name]
 
if len(matching) > 1:
raise NotImplementedError(
raise NotImplementedError(
"Comparison not implemented for multi-properties.")
"Comparison not implemented for multi-properties.")
for prop in new_entity.properties:
if len([0 for p in old_entity.properties if p.name == prop.name]) == 0:
if len([0 for p in old_entity.properties if p.name == prop.name]) == 0:
newdiff["properties"][prop.name] = {}
newdiff["properties"][prop.name] = {}
Loading