diff --git a/src/caosdb/high_level_api.py b/src/caosdb/high_level_api.py index 057640a999569e4a816b04b715872141daecd6c2..f42769a2e7c76cdbfe0638e5243bb1e0d97671a5 100644 --- a/src/caosdb/high_level_api.py +++ b/src/caosdb/high_level_api.py @@ -206,6 +206,7 @@ class CaosDBPythonEntity(object): val, datatype=ent.datatype) metadata = self.get_property_metadata(ent.name) + for prop_name in fields(metadata): k = prop_name.name if k == "importance": @@ -328,6 +329,11 @@ class CaosDBPythonEntity(object): if val is None: return None + elif isinstance(val, db.Entity): + # this needs to be checked as second case as it is the ONLY + # case which does not depend on pr + # TODO: we might need to pass through the reference container + return convert_to_python_object(val) elif pr is None: return val elif pr == DOUBLE: @@ -346,8 +352,6 @@ class CaosDBPythonEntity(object): return self._parse_datetime(val) elif is_list_datatype(pr): return self._type_converted_list(val, pr) - elif isinstance(val, db.Entity): - return convert_to_python_object(val) else: # Generic references to entities: return CaosDBPythonUnresolvedReference(val) @@ -558,7 +562,8 @@ BASE_ATTRIBUTES = ( def _single_convert_to_python_object(robj: CaosDBPythonEntity, - entity: db.Entity): + entity: db.Entity, + references: db.Container = None): """ Convert a db.Entity from the standard API to a (previously created) CaosDBPythonEntity from the high level API. @@ -566,6 +571,11 @@ def _single_convert_to_python_object(robj: CaosDBPythonEntity, This method will not resolve any unresolved references, so reference properties as well as parents will become unresolved references in the first place. + The optional third parameter can be used + to resolve references that occur in the converted entities and resolve them + to their correct representations. (Entities that are not found remain as + CaosDBPythonUnresolvedReferences.) + Returns the input object robj. """ for base_attribute in BASE_ATTRIBUTES: @@ -579,6 +589,9 @@ def _single_convert_to_python_object(robj: CaosDBPythonEntity, robj.add_parent(CaosDBPythonUnresolvedParent(id=parent.id, name=parent.name)) + # Resolve so far unresolved references also using the provided references container: + # TODO + return robj @@ -682,6 +695,7 @@ def _single_convert_to_entity(entity: db.Entity, def convert_to_entity(python_object, **kwargs): + raise NotImplementedError() if isinstance(python_object, db.Container): # Create a list of objects: @@ -700,24 +714,34 @@ def convert_to_entity(python_object, **kwargs): raise ValueError("Cannot convert an object of this type.") -def convert_to_python_object(entity): - """""" +def convert_to_python_object(entity: Union[db.Container, db.Entity], + references: db.Container = None): + """ + Convert either a container of CaosDB entities or a single CaosDB entity + into the high level representation. - if isinstance(entity, db.Container): - # Create a list of objects: + The optional second parameter can be used + to resolve references that occur in the converted entities and resolve them + to their correct representations. (Entities that are not found remain as + CaosDBPythonUnresolvedReferences.) + """ - return [convert_to_python_object(i) for i in entity] - elif isinstance(entity, db.Record): - return _single_convert_to_python_object(CaosDBPythonRecord(), entity) - elif isinstance(entity, db.RecordType): - return _single_convert_to_python_object( - CaosDBPythonRecordType(), entity) - elif isinstance(entity, db.File): - return _single_convert_to_python_object(CaosDBPythonFile(), entity) - elif isinstance(entity, db.Property): - return _single_convert_to_python_object(CaosDBPythonProperty(), entity) - elif isinstance(entity, db.Entity): - return _single_convert_to_python_object(CaosDBPythonEntity(), entity) - else: - raise ValueError("Cannot convert an object of this type.") + # TODO: check appropriateness of python classes as dict keys: + entity_map = { + db.Record: CaosDBPythonRecord, + db.RecordType: CaosDBPythonRecordType, + db.File: CaosDBPythonFile, + db.Property: CaosDBPythonProperty, + db.Entity: CaosDBPythonEntity} + if isinstance(entity, db.Container): + # Create a list of objects: + return [convert_to_python_object(i, references) for i in entity] + + for entity_type in entity_map: + if isinstance(entity, entity_type): + # TODO: mypy fails here, the case "db.Container" is already treated above + return _single_convert_to_python_object( + entity_map[entity_type](), entity, references) + raise ValueError("Cannot convert an object of this type.") +