diff --git a/src/caosdb/high_level_api.py b/src/caosdb/high_level_api.py index d4d89654a41ba03eb2fd3c141541e42e4a5f5bf8..c2f4259529705c1f396965fc1e6fb2aebf73d93d 100644 --- a/src/caosdb/high_level_api.py +++ b/src/caosdb/high_level_api.py @@ -47,6 +47,35 @@ from dataclasses import dataclass, fields from datetime import datetime from dateutil import parser + +def standard_type_for_high_level_type(high_level_record): + if type(high_level_record) == CaosDBPythonRecord: + return db.Record + elif type(high_level_record) == CaosDBPythonFile: + return db.File + elif type(high_level_record) == CaosDBPythonProperty: + return db.Property + elif type(high_level_record) == CaosDBPythonRecordType: + return db.RecordType + elif type(high_level_record) == CaosDBPythonEntity: + return db.Entity + raise RuntimeError("Incompatible type.") + + +def high_level_type_for_standard_type(standard_record): + if type(standard_record) == db.Record: + return CaosDBPythonRecord + elif type(standard_record) == db.File: + return CaosDBPythonFile + elif type(standard_record) == db.Property: + return CaosDBPythonProperty + elif type(standard_record) == db.RecordType: + return CaosDBPythonRecordType + elif type(standard_record) == db.Entity: + return CaosDBPythonEntity + raise RuntimeError("Incompatible type.") + + @dataclass class CaosDBPropertyMetaData: # name is already the name of the attribute @@ -364,7 +393,7 @@ class CaosDBPythonEntity(object): elif pr == TEXT: return str(val) elif pr == FILE: - return int(val) + return CaosDBPythonUnresolvedReference(val) elif pr == REFERENCE: return CaosDBPythonUnresolvedReference(val) elif pr == DATETIME: @@ -685,7 +714,8 @@ def _single_convert_to_entity(entity: db.Entity, if isinstance(propval, CaosDBPythonUnresolvedReference): propval = propval.id elif isinstance(propval, CaosDBPythonEntity): - propval = _single_convert_to_entity(db.Record(), propval) + propval = _single_convert_to_entity( + standard_type_for_high_level_type(propval)(), propval) elif isinstance(propval, list): raise NotImplementedError() @@ -731,23 +761,10 @@ def convert_to_python_object(entity: Union[db.Container, db.Entity], to their correct representations. (Entities that are not found remain as CaosDBPythonUnresolvedReferences.) """ - - # 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 type(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.") + return _single_convert_to_python_object( + high_level_type_for_standard_type(entity)(), entity, references) diff --git a/unittests/test_high_level_api.py b/unittests/test_high_level_api.py index fdf4aa08aaf698b1eb91b8bc679e337fdbb8c58e..2ca57c1108fb7e539bdec2f7a7976753c0901541 100644 --- a/unittests/test_high_level_api.py +++ b/unittests/test_high_level_api.py @@ -351,3 +351,48 @@ def test_files(): assert "path: test.dat" in str(obj) assert "file: /local/path/test.dat" in str(obj) + + # record with file property: + rec = db.Record() + rec.add_property(name="testfile", value=r) + assert rec.get_property("testfile").value.file == "/local/path/test.dat" + assert rec.get_property("testfile").value.path == "test.dat" + + obj = convert_to_python_object(rec) + assert obj.testfile.file == "/local/path/test.dat" + assert obj.testfile.path == "test.dat" + + rconv = convert_to_entity(obj) + assert rconv.get_property("testfile").value.file == "/local/path/test.dat" + assert rconv.get_property("testfile").value.path == "test.dat" + + # record with file property as reference: + rec = db.Record() + rec.add_property(name="testfile", value=2, datatype=db.FILE) + obj = convert_to_python_object(rec) + assert type(obj.testfile) == CaosDBPythonUnresolvedReference + assert obj.testfile.id == 2 + assert obj.get_property_metadata("testfile").datatype == db.FILE + + # without resolving references: + rconv = convert_to_entity(obj) + p = rconv.get_property("testfile") + assert p.value == 2 + assert p.datatype == db.FILE + + # with previously resolved reference (should not work here, because id is missing): + obj.resolve_references(True, db.Container().extend(r)) + rconv = convert_to_entity(obj) + p = rconv.get_property("testfile") + assert p.value == 2 + assert p.datatype == db.FILE + + # this time it must work: + r.id = 2 + obj.resolve_references(True, db.Container().extend(r)) + rconv = convert_to_entity(obj) + p = rconv.get_property("testfile") + assert type(p.value) == db.File + assert p.datatype == db.FILE + assert p.value.file == "/local/path/test.dat" + assert p.value.path == "test.dat"