Skip to content
Snippets Groups Projects
Commit aecc3406 authored by Alexander Schlemmer's avatar Alexander Schlemmer
Browse files

ENH: entities can automatically be retrieved on resolve

parent ba58a7c0
No related branches found
No related tags found
2 merge requests!57RELEASE 0.7.3,!52F refactor high level api
......@@ -93,15 +93,18 @@ def high_level_type_for_role(role: str):
def high_level_type_for_standard_type(standard_record: db.Entity):
if type(standard_record) == db.Record:
if not isinstance(standard_record, db.Entity):
raise ValueError()
role = standard_record.role
if role == "Record" or type(standard_record) == db.Record:
return CaosDBPythonRecord
elif type(standard_record) == db.File:
elif role == "File" or type(standard_record) == db.File:
return CaosDBPythonFile
elif type(standard_record) == db.Property:
elif role == "Property" or type(standard_record) == db.Property:
return CaosDBPythonProperty
elif type(standard_record) == db.RecordType:
elif role == "RecordType" or type(standard_record) == db.RecordType:
return CaosDBPythonRecordType
elif type(standard_record) == db.Entity:
elif role == "Entity" or type(standard_record) == db.Entity:
return CaosDBPythonEntity
raise RuntimeError("Incompatible type.")
......@@ -531,6 +534,14 @@ class CaosDBPythonEntity(object):
# don't do the lookup in the references container
return visited[propval.id]
if references is None:
ent = db.Entity(id=propval.id).retrieve()
obj = convert_to_python_object(ent, references)
visited[propval.id] = obj
if deep:
obj.resolve_references(deep, references, visited)
return obj
# lookup in container:
for ent in references:
# Entities in container without an ID will be skipped:
......@@ -556,6 +567,8 @@ class CaosDBPythonEntity(object):
references: Optional[db.Container]
A container with references that might be resolved.
If None is passed as the container, this function tries to resolve entities from a running
CaosDB instance directly.
"""
# This parameter is used in the recursion to keep track of already visited
......@@ -613,8 +626,14 @@ class CaosDBPythonEntity(object):
for parent in serialization["parents"]:
if "unresolved" in parent:
id = None
name = None
if "id" in parent:
id = parent["id"]
if "name" in parent:
name = parent["name"]
entity.add_parent(CaosDBPythonUnresolvedParent(
id=parent["id"], name=parent["name"]))
id=id, name=name))
else:
raise NotImplementedError()
......@@ -756,9 +775,11 @@ class CaosDBMultiProperty:
class CaosDBPythonFile(CaosDBPythonEntity):
def get_File(self, target=None):
f = db.File(id=self._id).retrieve()
self._file = f.download(target)
def download(self, target=None):
if self.id is None:
raise RuntimeError("Cannot download file when id is missing.")
f = db.File(id=self.id).retrieve()
return f.download(target)
BASE_ATTRIBUTES = (
......@@ -974,3 +995,13 @@ def create_entity_container(record: CaosDBPythonEntity):
return db.Container().extend(lse)
def query(query: str, resolve_references: bool = True, references: db.Container = None):
"""
"""
res = db.execute_query(query)
objects = convert_to_python_object(res)
if resolve_references:
for obj in objects:
obj.resolve_references(True, references)
return objects
......@@ -532,9 +532,14 @@ def test_type_conversion():
with pytest.raises(RuntimeError, match="Incompatible type."):
standard_type_for_high_level_type(42, True)
with pytest.raises(RuntimeError, match="Incompatible type."):
with pytest.raises(ValueError):
high_level_type_for_standard_type("ajsdkfjasfkj")
with pytest.raises(RuntimeError, match="Incompatible type."):
class IncompatibleType(db.Entity):
pass
high_level_type_for_standard_type(IncompatibleType())
def test_deserialization():
r = db.Record(id=17, name="test")
......@@ -585,3 +590,7 @@ def test_deserialization():
serial = obj.serialize()
obj_des = CaosDBPythonEntity.deserialize(serial)
assert obj.serialize() == obj_des.serialize()
def test_recursion():
pass
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment