diff --git a/src/caosdb/high_level_api.py b/src/caosdb/high_level_api.py index 365cd1331a7a88d0931ecab8e4d3ec79e28563c2..c8ae283bb2641a72bdbf6742c954c74dccb7bd37 100644 --- a/src/caosdb/high_level_api.py +++ b/src/caosdb/high_level_api.py @@ -31,7 +31,10 @@ This is refactored from apiutils. """ from caosdb.common.datatype import (BOOLEAN, DATETIME, DOUBLE, FILE, INTEGER, - REFERENCE, TEXT, is_list_datatype, get_list_datatype) + REFERENCE, TEXT, + is_list_datatype, + get_list_datatype, + is_reference) import caosdb as db from .apiutils import get_type_of_entity_with @@ -39,7 +42,7 @@ from .apiutils import get_type_of_entity_with from typing import Any, Optional, List, Union, Dict from dataclasses import dataclass - +from datetime import datetime @dataclass class CaosDBPropertyMetaData: @@ -230,50 +233,67 @@ class CaosDBPythonEntity(object): """ self._id = idx - def _type_converted_list(self, val, pr): - """Convert a list to a python list of the correct type.""" - prrealpre = pr.replace("<", "<").replace(">", ">") - prreal = prrealpre[prrealpre.index("<") + 1:prrealpre.rindex(">")] + def _type_converted_list(self, + val: List, + pr: str): + """ + Convert a list to a python list of the correct type. + + val: List + The value of a property containing the list. + + pr: str + The datatype according to the database entry. + """ + if not is_list_datatype(pr): + raise RuntimeError("Not a list.") + prreal = get_list_datatype(pr) lst = [self._type_converted_value(i, prreal) for i in val] return ([i[0] for i in lst], lst[0][1]) - def _type_converted_value(self, val, pr): - """Convert val to the correct type which is indicated by the database + def _type_converted_value(self, + val: Any, + pr: str): + """ + Convert val to the correct type which is indicated by the database type string in pr. - Returns a tuple with two entries: - - the converted value - - True if the value has to be interpreted as an id acting as a reference - - If datatype is None return the tuple: - (value, False) + References with ids will be turned into CaosDBPythonUnresolvedReference. """ if val is None: - return (None, False) + return None elif pr is None: - return (val, False) + return val elif pr == DOUBLE: - return (float(val), False) + return float(val) elif pr == BOOLEAN: - return (bool(val), False) + return bool(val) elif pr == INTEGER: - return (int(val), False) + return int(val) elif pr == TEXT: - return (val, False) + return str(val) elif pr == FILE: - return (int(val), False) + return int(val) elif pr == REFERENCE: - return (int(val), True) + return CaosDBPythonUnresolvedReference(val) elif pr == DATETIME: - return (val, False) - elif pr[0:4] == "LIST": + return val + elif is_list_datatype(pr): return self._type_converted_list(val, pr) elif isinstance(val, db.Entity): - return (convert_to_python_object(val), False) + return convert_to_python_object(val) else: - return (int(val), True) + # Generic references to entities: + return CaosDBPythonUnresolvedReference(val) + + def _parse_datetime(self, val): + """ + Convert val into a datetime object. + """ + # TODO: try different representations + return datetime.strptime("%Y-%m-%d %H:%M:%S", val) def attribute_as_list(self, name): """This is a workaround for the problem that lists containing only one