From 472b797233097b7d6c4e8b26f2e9efd41965bd66 Mon Sep 17 00:00:00 2001 From: Alexander Schlemmer <alexander@mail-schlemmer.de> Date: Tue, 1 Feb 2022 14:59:24 +0100 Subject: [PATCH] ENH: new function to merge entities --- src/caosdb/apiutils.py | 44 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/caosdb/apiutils.py b/src/caosdb/apiutils.py index e126b843..e4d4df25 100644 --- a/src/caosdb/apiutils.py +++ b/src/caosdb/apiutils.py @@ -712,10 +712,52 @@ def copy_entity(entity: Entity): return new +def merge_entities(entity_a: Entity, entity_b: Entity): + """ + Create a new entity which is a copy of entity_a and merge it with entity_b such that + it compare_entities would report zero differences. + """ + new = copy_entity(entity_a) + + # Compare both entities: + diff_r1, diff_r2 = compare_entities(entity_a, entity_b) + + # Go through the comparison and try to apply changes to entity_a: + for key in diff_r2["parents"]: + new.add_parent(entity_b.get_parent(key)) + + for key in diff_r2["properties"]: + if key in diff_r1["properties"]: + if (diff_r1["properties"][key]["importance"] != + diff_r2["properties"][key]["importance"]): + raise NotImplementedError() + + for attribute in ("datatype", "unit", "value"): + if diff_r1["properties"][key][attribute] is None: + setattr(new.get_property(key), attribute, + diff_r2["properties"][key][attribute]) + else: + raise RuntimeError("Merge conflict.") + else: + new.add_property( + entity_b.get_property(key), + importance=entity_b.get_importance(key)) + + for special_attribute in ("name", "description"): + sa_new = getattr(new, special_attribute) + sa_b = getattr(entity_b, special_attribute) + if sa_new != sa_b: + if sa_new is None: + setattr(new, special_attribute, sa_b) + else: + raise RuntimeError("Merge conflict.") + return new + + def describe_diff(olddiff, newdiff, name=None, as_update=True): description = "" - for attr in list(set(list(olddiff.keys())+list(newdiff.keys()))): + for attr in list(set(list(olddiff.keys()) + list(newdiff.keys()))): if attr == "parents" or attr == "properties": continue description += "{} differs:\n".format(attr) -- GitLab