diff --git a/docs/source/howto/query.rst b/docs/source/howto/query.rst index 4916cb508e..a381a42412 100644 --- a/docs/source/howto/query.rst +++ b/docs/source/howto/query.rst @@ -99,7 +99,6 @@ For example, you can iterate over the results of your query in a for loop: This avoids loading the entire query result into memory, and it also delays committing changes made to AiiDA objects inside the loop until the end of the loop is reached. If an exception is raised before the loop ends, all changes are reverted. - .. _how-to:query:filters: Filters @@ -160,6 +159,59 @@ In case you want all calculation jobs with state ``finished`` or ``excepted``, y }, ) +.. _how-to:query:filters:programmatic: + +Programmatic syntax for filters +------------------------------- + +.. versionadded:: 2.6 + +Filter keys may be defined programmatically, providing in modern IDEs (including AiiDA's ``verdi shell``) autocompletion of fields and operators. +For example, the above query may be given as + +.. code-block:: python + + qb = QueryBuilder() + qb.append( + CalcJobNode, + filters={ + CalcJobNode.fields.process_state: {'in': ['finished', 'excepted']}, + }, + ) + +In this approach, ``CalcJobNode.fields.`` will suggest (autocomplete) the queryable fields of ``CalcJobNode`` allowing the user to explore the node's attributes directly while constructing the query. + +Alternatively, the entire filtering expression may be provided programmatically as logical expressions: + +.. code-block:: python + + qb = QueryBuilder() + qb.append( + CalcJobNode, + filters=CalcJobNode.fields.process_state.in_(['finished', 'excepted']), + ) + +.. note:: + + Logical operations are distributed by type. As such, ``Node.fields..`` will `only` provide the :ref:`supported operations` for the type of ``some_field``, in this case ``==``, ``in_``, ``like``, and ``ilike``, for type ``str``. + +Logical expressions may be strung together with ``&`` and ``|`` to construct complex queries. + +.. code-block:: python + + filters=( + (Node.fields.ctime < datetime(2030, 1, 1)) + & ( + (Node.fields.pk.in_([4, 8, 15, 16, 23, 42])) + | (Node.fields.label.like("%some_label%")) + ) + & (Node.fields.extras.has_key("some_key")) + ) + +.. tip:: + + ``()`` may be used to override the natural precedence of ``|``. + .. _how-to:query:filters:operator-negations: Operator negations @@ -185,6 +237,14 @@ So, to query for all calculation jobs that are not a ``finished`` or ``excepted` A complete list of all available operators can be found in the :ref:`advanced querying section`. +.. _how-to:query:filters:operator-negations:new: + +.. versionadded:: 2.6 + Programamtic filter negation + + In the new :ref:`logical expression syntax`, negation can be achieved by prepending ``~`` to any expression. + For example ``~(Int.fields.value < 5)`` is equivalent to ``Int.fields.value >= 5``. + .. _how-to:query:relationships: Relationships @@ -273,10 +333,28 @@ This can be used to project the values of nested dictionaries as well. Be aware that for consistency, ``QueryBuilder.all()`` / ``iterall()`` always returns a list of lists, even if you only project one property of a single entity. Use ``QueryBuilder.all(flat=True)`` to return the query result as a flat list in this case. -As mentioned in the beginning, this section provides only a brief introduction to the :class:`~aiida.orm.querybuilder.QueryBuilder`'s basic functionality. -To learn about more advanced queries, please see :ref:`the corresponding topics section`. +.. _how-to:query:projections:programmatic: + +.. versionadded:: 2.6 + Programmatic syntax for projections + Similar to :ref:`filters`, projections may also be provided programmatically, leveraging the autocompletion feature of modern IDEs. + .. code-block:: python + + qb = QueryBuilder() + qb.append( + Int, + project=[ + Int.fields.pk, + Int.fields.value, + ], + ) + +---- + +As mentioned in the beginning, this section provides only a brief introduction to the :class:`~aiida.orm.querybuilder.QueryBuilder`'s basic functionality. +To learn about more advanced queries, please see :ref:`the corresponding topics section`. .. _how-to:query:shortcuts: diff --git a/docs/source/topics/data_types.rst b/docs/source/topics/data_types.rst index 2e2171278d..a2309d4e66 100644 --- a/docs/source/topics/data_types.rst +++ b/docs/source/topics/data_types.rst @@ -1375,3 +1375,34 @@ Therefore, big data (think large files), whose content does not necessarily need A data type may safely use both the database and file repository in parallel for individual properties. Properties stored in the database are stored as *attributes* of the node. The node class has various methods to set these attributes, such as :py:meth:`~aiida.orm.nodes.attributes.NodeAttributes.set` and :py:meth:`~aiida.orm.nodes.attributes.NodeAttributes.set_many`. + +Fields +------ + +.. versionadded:: 2.6 + +The attributes of new data types may be exposed to end users by explicitly defining each attribute field under the ``__qb_fields__`` class attribute of the new data class. + +.. code-block:: python + + from aiida.orm.fields import add_field + + class NewData(Data): + """A new data type.""" + + __qb_fields__ = [ + add_field( + key='frontend_key', + alias='backend_key', # optional mapping to a backend key, if different (only allowed for attribute fields) + dtype=str, + is_attribute=True, # signalling if field is an attribute field (default is `True`) + is_subscriptable=False, # signalling subscriptability for dictionary fields + doc='An example field', + ) + ] + +The internal mechanics of ``aiida.orm.fields`` will dynamically add ``frontend_key`` to the ``fields`` attribute of the new data type. The construction of ``fields`` follows the rules of inheritance, such that other than its own fields, ``NewData.fields`` will also inherit the fields of its parents, following the inheritance tree up to the root ``Entity`` ancestor. This enhances the usability of the new data type, for example, allowing the end user to programmatically define :ref:`filters` and :ref:`projections` when using AiiDA's :py:class:`~aiida.orm.querybuilder.QueryBuilder`. + +.. note:: + + :py:meth:`~aiida.orm.fields.add_field` will return the flavor of :py:class:`~aiida.orm.fields.QbField` associated with the type of the field defined by the ``dtype`` argument, which can be given as a primitive type or a ``typing``-module type hint, e.g. ``Dict[str, Any]``. When using the data class in queries, the logical operators available to the user will depend on the flavor of :py:class:`~aiida.orm.fields.QbField` assigned to the field. diff --git a/docs/source/topics/database.rst b/docs/source/topics/database.rst index d0227efc90..c31294067d 100644 --- a/docs/source/topics/database.rst +++ b/docs/source/topics/database.rst @@ -178,13 +178,26 @@ List of all operators: | ``contains`` | lists | ``'attributes.some_key': {'contains': ['a', 'b']}`` | Filter for lists that should contain certain values. | +--------------+-------------+-------------------------------------------------------+------------------------------------------------------------------------------+ -As mentioned in the :ref:`section about operatior negations` all operators can be turned into their associated negation (``NOT`` operator) by adding a ``!`` in front of the operator. +.. versionadded:: 2.6 + Logical expression syntax + + In the new logical expression syntax for :ref:`filters` and :ref:`projections`, the above operations are distributed by type. + When using the autocompletion feature in constructing query expressions, only operations associated with the type of the queried field will be presented. + + For example, ``Node.fields.uuid`` is a string type, and as such, ``Node.fields.uuid.`` will, in addition to ``==`` and ``in_``, only suggest ``like`` and ``ilike``. + + +As mentioned in the :ref:`section about operator negations` all operators can be turned into their associated negation (``NOT`` operator) by adding a ``!`` in front of the operator. + +.. versionadded:: 2.6 + Programmatic filter negation + + In the new logical expression syntax, negation is defined with ``~``, such that ``~(Node.fields.some_field < 1)`` is equivalent to ``Node.fields.some_field >= 1``. .. note:: The form of (negation) operators in the rendered SQL may differ from the ones specified in the ``QueryBuilder`` instance. For example, the ``!==`` operator of the ``QueryBuilder`` will be rendered to ``!=`` in SQL. - .. _topics:database:advancedquery:tables:relationships: List of all relationships: diff --git a/src/aiida/orm/__init__.py b/src/aiida/orm/__init__.py index eb75264dac..2e1fe9618d 100644 --- a/src/aiida/orm/__init__.py +++ b/src/aiida/orm/__init__.py @@ -83,7 +83,6 @@ 'PortableCode', 'ProcessNode', 'ProjectionData', - 'QbAttrField', 'QbField', 'QbFieldFilters', 'QbFields', diff --git a/src/aiida/orm/authinfos.py b/src/aiida/orm/authinfos.py index 21ee823258..cf27fb93e8 100644 --- a/src/aiida/orm/authinfos.py +++ b/src/aiida/orm/authinfos.py @@ -14,7 +14,7 @@ from aiida.plugins import TransportFactory from . import entities, users -from .fields import QbField +from .fields import add_field if TYPE_CHECKING: from aiida.orm import Computer, User @@ -45,13 +45,38 @@ class AuthInfo(entities.Entity['BackendAuthInfo', AuthInfoCollection]): _CLS_COLLECTION = AuthInfoCollection - __qb_fields__ = ( - QbField('enabled', dtype=bool, doc='Whether the instance is enabled'), - QbField('auth_params', dtype=Dict[str, Any], doc='Dictionary of authentication parameters'), - QbField('metadata', dtype=Dict[str, Any], doc='Dictionary of metadata'), - QbField('computer_pk', 'dbcomputer_id', dtype=int, doc='The PK of the computer'), - QbField('user_pk', 'aiidauser_id', dtype=int, doc='The PK of the user'), - ) + __qb_fields__ = [ + add_field( + 'enabled', + dtype=bool, + is_attribute=False, + doc='Whether the instance is enabled', + ), + add_field( + 'auth_params', + dtype=Dict[str, Any], + is_attribute=False, + doc='Dictionary of authentication parameters', + ), + add_field( + 'metadata', + dtype=Dict[str, Any], + is_attribute=False, + doc='Dictionary of metadata', + ), + add_field( + 'computer_pk', + dtype=int, + is_attribute=False, + doc='The PK of the computer', + ), + add_field( + 'user_pk', + dtype=int, + is_attribute=False, + doc='The PK of the user', + ), + ] PROPERTY_WORKDIR = 'workdir' diff --git a/src/aiida/orm/comments.py b/src/aiida/orm/comments.py index 92a721fc7b..00a1556f82 100644 --- a/src/aiida/orm/comments.py +++ b/src/aiida/orm/comments.py @@ -13,7 +13,7 @@ from aiida.manage import get_manager from . import entities, users -from .fields import QbField +from .fields import add_field if TYPE_CHECKING: from aiida.orm import Node, User @@ -64,14 +64,44 @@ class Comment(entities.Entity['BackendComment', CommentCollection]): _CLS_COLLECTION = CommentCollection - __qb_fields__ = ( - QbField('uuid', dtype=str, doc='The UUID of the comment'), - QbField('ctime', dtype=datetime, doc='Creation time of the comment'), - QbField('mtime', dtype=datetime, doc='Modified time of the comment'), - QbField('content', dtype=str, doc='Content of the comment'), - QbField('user_pk', 'user_id', dtype=int, doc='User PK that created the comment'), - QbField('node_pk', 'dbnode_id', dtype=int, doc='Node PK that the comment is attached to'), - ) + __qb_fields__ = [ + add_field( + 'uuid', + dtype=str, + is_attribute=False, + doc='The UUID of the comment', + ), + add_field( + 'ctime', + dtype=datetime, + is_attribute=False, + doc='Creation time of the comment', + ), + add_field( + 'mtime', + dtype=datetime, + is_attribute=False, + doc='Modified time of the comment', + ), + add_field( + 'content', + dtype=str, + is_attribute=False, + doc='Content of the comment', + ), + add_field( + 'user_pk', + dtype=int, + is_attribute=False, + doc='User PK that created the comment', + ), + add_field( + 'node_pk', + dtype=int, + is_attribute=False, + doc='Node PK that the comment is attached to', + ), + ] def __init__( self, node: 'Node', user: 'User', content: Optional[str] = None, backend: Optional['StorageBackend'] = None diff --git a/src/aiida/orm/computers.py b/src/aiida/orm/computers.py index ef82768d14..588d16602b 100644 --- a/src/aiida/orm/computers.py +++ b/src/aiida/orm/computers.py @@ -16,7 +16,7 @@ from aiida.plugins import SchedulerFactory, TransportFactory from . import entities, users -from .fields import QbField +from .fields import add_field if TYPE_CHECKING: from aiida.orm import AuthInfo, User @@ -72,15 +72,50 @@ class Computer(entities.Entity['BackendComputer', ComputerCollection]): _CLS_COLLECTION = ComputerCollection - __qb_fields__ = ( - QbField('uuid', dtype=str, doc='The UUID of the computer'), - QbField('label', dtype=str, doc='Label for the computer'), - QbField('description', dtype=str, doc='Description of the computer'), - QbField('hostname', dtype=str, doc='Hostname of the computer'), - QbField('transport_type', dtype=str, doc='Transport type of the computer'), - QbField('scheduler_type', dtype=str, doc='Scheduler type of the computer'), - QbField('metadata', dtype=Dict[str, Any], doc='Metadata of the computer'), - ) + __qb_fields__ = [ + add_field( + 'uuid', + dtype=str, + is_attribute=False, + doc='The UUID of the computer', + ), + add_field( + 'label', + dtype=str, + is_attribute=False, + doc='Label for the computer', + ), + add_field( + 'description', + dtype=str, + is_attribute=False, + doc='Description of the computer', + ), + add_field( + 'hostname', + dtype=str, + is_attribute=False, + doc='Hostname of the computer', + ), + add_field( + 'transport_type', + dtype=str, + is_attribute=False, + doc='Transport type of the computer', + ), + add_field( + 'scheduler_type', + dtype=str, + is_attribute=False, + doc='Scheduler type of the computer', + ), + add_field( + 'metadata', + dtype=Dict[str, Any], + is_attribute=False, + doc='Metadata of the computer', + ), + ] def __init__( self, diff --git a/src/aiida/orm/entities.py b/src/aiida/orm/entities.py index f1f4a425c2..dc93ced2e5 100644 --- a/src/aiida/orm/entities.py +++ b/src/aiida/orm/entities.py @@ -21,7 +21,7 @@ from aiida.common.warnings import warn_deprecation from aiida.manage import get_manager -from .fields import EntityFieldMeta, QbField, QbFields +from .fields import EntityFieldMeta, QbField, QbFields, add_field if TYPE_CHECKING: from aiida.orm.implementation import BackendEntity, StorageBackend @@ -176,7 +176,14 @@ class Entity(abc.ABC, Generic[BackendEntityType, CollectionType], metaclass=Enti fields: QbFields = QbFields() - __qb_fields__: Sequence[QbField] = (QbField('pk', 'id', dtype=int, doc='The primary key of the entity'),) + __qb_fields__: Sequence[QbField] = [ + add_field( + 'pk', + dtype=int, + is_attribute=False, + doc='The primary key of the entity', + ), + ] @classproperty def objects(cls: EntityType) -> CollectionType: # noqa: N805 diff --git a/src/aiida/orm/fields.py b/src/aiida/orm/fields.py index 3af99f3a4c..4291c49f28 100644 --- a/src/aiida/orm/fields.py +++ b/src/aiida/orm/fields.py @@ -7,107 +7,165 @@ # For further information please visit http://www.aiida.net # ########################################################################### """Module which provides decorators for AiiDA ORM entity -> DB field mappings.""" +import datetime +import typing as t from abc import ABCMeta from copy import deepcopy +from functools import singledispatchmethod from pprint import pformat -from typing import Any, Dict, Iterable, Optional, Sequence, Tuple, Union -__all__ = ('QbAttrField', 'QbField', 'QbFields', 'QbFieldFilters') +from aiida.common.lang import isidentifier + +__all__ = ( + 'QbField', + 'QbFieldFilters', + 'QbFields', +) + + +def extract_root_type(dtype: t.Any) -> t.Any: + """Recursively search for the primitive root type. + + >>> extract_root_type(List[str]) -> list + >>> extract_root_type(Optional[List[str]]) -> list + """ + origin = t.get_origin(dtype) + if origin: + if origin is t.Union: + return extract_root_type(t.get_args(dtype)[0]) + else: + return origin + else: + return dtype class QbField: """A field of an ORM entity, accessible via the ``QueryBuilder``""" - __slots__ = ('_key', '_qb_field', '_doc', '_dtype', '_subscriptable') + __slots__ = ( + '_key', + '_backend_key', + '_doc', + '_dtype', + '_is_attribute', + '_is_subscriptable', + ) def __init__( self, key: str, - qb_field: Optional[str] = None, + alias: t.Optional[str] = None, *, - dtype: Optional[Any] = None, + dtype: t.Optional[t.Any] = None, doc: str = '', - subscriptable: bool = False, + is_attribute: bool = True, + is_subscriptable: bool = False, ) -> None: """Initialise a ORM entity field, accessible via the ``QueryBuilder`` :param key: The key of the field on the ORM entity - :param qb_field: The name of the field in the QueryBuilder, if not equal to ``key`` + :param alias: The alias in the storage backend for the key, if not equal to ``key`` :param dtype: The data type of the field. If None, the field is of variable type. :param doc: A docstring for the field - :param subscriptable: If True, a new field can be created by ``field["subkey"]`` + :param is_attribute: If True, the ``backend_key`` property will prepend "attributes." to field name + :param is_subscriptable: If True, a new field can be created by ``field["subkey"]`` """ self._key = key - self._qb_field = qb_field if qb_field is not None else key + self._backend_key = alias if alias is not None else key self._doc = doc self._dtype = dtype - self._subscriptable = subscriptable + self._is_attribute = is_attribute + self._is_subscriptable = is_subscriptable @property def key(self) -> str: return self._key @property - def qb_field(self) -> str: - return self._qb_field + def backend_key(self) -> str: + if self._is_attribute: + return f'attributes.{self._backend_key}' + return self._backend_key @property def doc(self) -> str: return self._doc @property - def dtype(self) -> Optional[Any]: + def dtype(self) -> t.Optional[t.Any]: return self._dtype + def get_root_type(self) -> t.Optional[t.Any]: + """Return the primitive root type.""" + return extract_root_type(self._dtype) + + @property + def is_attribute(self) -> bool: + return self._is_attribute + @property - def subscriptable(self) -> bool: - return self._subscriptable - - def _repr_type(self, value: Any) -> str: - """Return a string representation of the type of the value""" - if value == type(None): - return 'None' - if isinstance(value, type): - # basic types like int, str, etc. - return value.__qualname__ - if hasattr(value, '__origin__') and value.__origin__ == Union: - return 'typing.Union[' + ','.join(self._repr_type(t) for t in value.__args__) + ']' - return str(value) + def is_subscriptable(self) -> bool: + return self._is_subscriptable def __repr__(self) -> str: - dtype = self._repr_type(self.dtype) if self.dtype else '' + type_str = self._get_dtype_as_str() if self._dtype else '' return ( f'{self.__class__.__name__}({self.key!r}' - + (f', {self._qb_field!r}' if self._qb_field != self.key else '') - + (f', dtype={dtype}' if self.dtype else '') - + (f', subscriptable={self.subscriptable!r}' if self.subscriptable else '') + + (f', {self._backend_key!r}' if self._backend_key != self.key else '') + + (f', dtype={type_str}' if self._dtype else '') + + (f', is_attribute={self.is_attribute}') + + (f', is_subscriptable={self.is_subscriptable!r}' if self.is_subscriptable else '') + ')' ) def __str__(self) -> str: - type_str = ( - '?' if self.dtype is None else (self.dtype.__name__ if isinstance(self.dtype, type) else str(self.dtype)) - ) - type_str = type_str.replace('typing.', '') - return f"{self.__class__.__name__}({self.qb_field}{'.*' if self.subscriptable else ''}) -> {type_str}" - - def __getitem__(self, key: str) -> 'QbField': - """Return a new QbField with a nested key.""" - if not self.subscriptable: - raise IndexError('This field is not subscriptable') - return self.__class__(f'{self.key}.{key}', f'{self.qb_field}.{key}') + class_name = self.__class__.__name__ + field_name = f'{self.backend_key}{".*" if self.is_subscriptable else ""}' + type_str = self._get_dtype_as_str() + return f'{class_name}({field_name}) -> {type_str}' def __hash__(self): - return hash((self.key, self.qb_field)) - - # methods for creating QueryBuilder filter objects - # these methods mirror the syntax within SQLAlchemy + return hash((self.key, self.backend_key)) def __eq__(self, value): return QbFieldFilters(((self, '==', value),)) def __ne__(self, value): - return QbFieldFilters(((self, '!=', value),)) + return QbFieldFilters(((self, '!==', value),)) + + def in_(self, value: t.Iterable[t.Any]): + """Return a filter for only values in the list""" + try: + set(value) + except TypeError: + raise TypeError('in_ must be iterable') + return QbFieldFilters(((self, 'in', value),)) + + def _get_dtype_as_str(self) -> str: + """Return field type as processed string. + + >>> None -> ? + >>> str -> str + >>> typing.Optional[str] -> Optional[str] + >>> typing.Dict[typing.List[str]] -> Dict[List[str]] + """ + if self._dtype: + if t.get_origin(self._dtype): + type_str = str(self._dtype).replace('typing.', '') + else: + type_str = self._dtype.__name__ + else: + type_str = '?' + return type_str + + if t.TYPE_CHECKING: + + def __getitem__(self, key: str) -> 'QbField': + ... + + +class QbNumericField(QbField): + """A numeric (`int`, `float`, `datetime`) flavor of `QbField`.""" def __lt__(self, value): return QbFieldFilters(((self, '<', value),)) @@ -121,6 +179,36 @@ def __gt__(self, value): def __ge__(self, value): return QbFieldFilters(((self, '>=', value),)) + +class QbArrayField(QbField): + """An array (`list`) flavor of `QbField`.""" + + def contains(self, value): + """Return a filter for only values containing these items""" + return QbFieldFilters(((self, 'contains', value),)) + + def of_length(self, value: int): + """Return a filter for only array values of this length.""" + if not isinstance(value, int): + raise TypeError('of_length must be an integer') + return QbFieldFilters(((self, 'of_length', value),)) + + def longer(self, value: int): + """Return a filter for only array values longer than this length.""" + if not isinstance(value, int): + raise TypeError('longer must be an integer') + return QbFieldFilters(((self, 'longer', value),)) + + def shorter(self, value: int): + """Return a filter for only array values shorter than this length.""" + if not isinstance(value, int): + raise TypeError('shorter must be an integer') + return QbFieldFilters(((self, 'shorter', value),)) + + +class QbStrField(QbField): + """A string (`str`) flavor of `QbField`.""" + def like(self, value: str): """Return a filter for only string values matching the wildcard string. @@ -141,57 +229,31 @@ def ilike(self, value: str): raise TypeError('ilike must be a string') return QbFieldFilters(((self, 'ilike', value),)) - def in_(self, value: Iterable[Any]): - """Return a filter for only values in the list""" - try: - value = set(value) - except TypeError: - raise TypeError('in_ must be iterable') - return QbFieldFilters(((self, 'in', value),)) - - def not_in(self, value: Iterable[Any]): - """Return a filter for only values not in the list""" - try: - value = set(value) - except TypeError: - raise TypeError('in_ must be iterable') - return QbFieldFilters(((self, '!in', value),)) - - # JSONB only, we should only show these if the field is a JSONB field - - # def contains(self, value): - # """Return a filter for only values containing these items""" - # return QbFieldFilters(((self, 'contains', value),)) - # def has_key(self, value): - # """Return a filter for only values with these keys""" - # return QbFieldFilters(((self, 'has_key', value),)) +class QbDictField(QbField): + """A dictionary (`dict`) flavor of `QbField`.""" - # def of_length(self, value: int): - # """Return a filter for only array values of this length.""" - # if not isinstance(value, int): - # raise TypeError('of_length must be an integer') - # return QbFieldFilters(((self, 'of_length', value),)) + def has_key(self, value): + """Return a filter for only values with these keys""" + return QbFieldFilters(((self, 'has_key', value),)) - # def longer(self, value: int): - # """Return a filter for only array values longer than this length.""" - # if not isinstance(value, int): - # raise TypeError('longer must be an integer') - # return QbFieldFilters(((self, 'longer', value),)) - - # def shorter(self, value: int): - # """Return a filter for only array values shorter than this length.""" - # if not isinstance(value, int): - # raise TypeError('shorter must be an integer') - # return QbFieldFilters(((self, 'shorter', value),)) + def __getitem__(self, key: str) -> 'QbAttrField': + """Return a new `QbField` with a nested key.""" + if not self.is_subscriptable: + raise IndexError('This field is not subscriptable') + return QbAttrField( + f'{self.key}.{key}', + f'{self._backend_key}.{key}' if self.is_attribute else None, + is_attribute=self.is_attribute, + ) -class QbAttrField(QbField): - """An attribute field of an ORM entity, accessible via the ``QueryBuilder``""" +class QbAttrField(QbNumericField, QbArrayField, QbStrField, QbDictField): + """A generic flavor of `QbField` covering all operations.""" - @property - def qb_field(self) -> str: - return f'attributes.{self._qb_field}' + def of_type(self, value): + """Return a filter for only values of this type.""" + return QbFieldFilters(((self, 'of_type', value),)) class QbFieldFilters: @@ -199,27 +261,103 @@ class QbFieldFilters: __slots__ = ('filters',) - def __init__(self, filters: Sequence[Tuple[QbField, str, Any]]): - self.filters = list(filters) + def __init__( + self, + filters: t.Union[t.Sequence[t.Tuple[QbField, str, t.Any]], dict], + ): + self.filters: t.Dict[str, t.Any] = {} + self.add_filters(filters) + + def as_dict(self) -> t.Dict[str, t.Any]: + """Return the filters dictionary.""" + return self.filters + + def items(self): + """Return an items view of the filters for use in the QueryBuilder.""" + return self.filters.items() + + @singledispatchmethod + def add_filters(self, filters: dict): + self.filters.update(filters) + + @add_filters.register(list) + @add_filters.register(tuple) + def _(self, filters): + field: QbField + for field, comparator, value in filters: + qb_field = field.backend_key + if qb_field in self.filters: + self.filters['and'] = [ + {qb_field: self.filters.pop(qb_field)}, + {qb_field: {comparator: value}}, + ] + else: + self.filters[qb_field] = {comparator: value} def __repr__(self) -> str: return f'QbFieldFilters({self.filters})' - def as_dict(self) -> Dict[QbField, Any]: - """Return the filters as a dictionary, for use in the QueryBuilder.""" - output: Dict[QbField, Any] = {} - for field, comparator, value in self.filters: - if field in output: - output[field]['and'].append({comparator: value}) - else: - output[field] = {'and': [{comparator: value}]} - return output + def __getitem__(self, key: str) -> t.Any: + return self.filters[key] + + def __contains__(self, key: str) -> bool: + return key in self.filters + + def __eq__(self, other: object) -> bool: + """``a == b`` checks if `a.filters == b.filters`.""" + if not isinstance(other, QbFieldFilters): + raise TypeError(f'Cannot compare QbFieldFilters to {type(other)}') + return self.filters == other.filters def __and__(self, other: 'QbFieldFilters') -> 'QbFieldFilters': - """Concatenate two QbFieldFilters objects: ``a & b``.""" + """``a & b`` -> {'and': [`a.filters`, `b.filters`]}.""" + return self._resolve_redundancy(other, 'and') or QbFieldFilters({'and': [self.filters, other.filters]}) + + def __or__(self, other: 'QbFieldFilters') -> 'QbFieldFilters': + """``a | b`` -> {'or': [`a.filters`, `b.filters`]}.""" + return self._resolve_redundancy(other, 'or') or QbFieldFilters({'or': [self.filters, other.filters]}) + + def __invert__(self) -> 'QbFieldFilters': + """~(a > b) -> a !> b; ~(a !> b) -> a > b""" + filters = deepcopy(self.filters) + if 'and' in filters: + filters['!and'] = filters.pop('and') + elif 'or' in filters: + filters['!or'] = filters.pop('or') + elif '!and' in filters: + filters['and'] = filters.pop('!and') + elif '!or' in filters: + filters['or'] = filters.pop('!or') + else: + key, args = next(iter(filters.items())) + operator, value = next(iter(args.items())) + operator = operator[1:] if '!' in operator else f'!{operator}' + filters[key] = {operator: value} + return QbFieldFilters(filters) + + def _resolve_redundancy(self, other: 'QbFieldFilters', logical: str) -> t.Optional['QbFieldFilters']: + """Resolve redundant filters and nested logical operators.""" + if not isinstance(other, QbFieldFilters): - raise TypeError(f'Cannot add QbFieldFilters and {type(other)}') - return QbFieldFilters(self.filters + other.filters) + raise TypeError(f'Cannot combine QbFieldFilters and {type(other)}') + + # same filters + if other == self: + return self + + # self is already wrapped in `logical` + # append other to self + if logical in self.filters: + self[logical].append(other.filters) + return self + + # other is already wrapped in `logical` + # insert self in other + if logical in other: + other[logical].insert(0, self.filters) + return other + + return None class QbFields: @@ -227,7 +365,7 @@ class QbFields: __isabstractmethod__ = False - def __init__(self, fields: Optional[Dict[str, QbField]] = None): + def __init__(self, fields: t.Optional[t.Dict[str, QbField]] = None): self._fields = fields or {} def __repr__(self) -> str: @@ -287,11 +425,75 @@ def __init__(cls, name, bases, classdict): # __qb_fields__ should be a list of QbField instances if key == '__qb_fields__': assert isinstance( - attr, Sequence + attr, t.Sequence ), f"class '{cls}' has a '__qb_fields__' attribute, but it is not a sequence" for field in attr: if not isinstance(field, QbField): raise ValueError(f"__qb_fields__ attribute of class '{cls}' must be list of QbField instances") - fields[field.key] = field + if field.key == 'value': + if dtype := getattr(cls, '_type', None): + value_field = add_field( + 'value', + dtype=dtype, + doc='The value of the data', + ) + + fields[field.key] = value_field + else: + fields[field.key] = field cls.fields = QbFields({key: fields[key] for key in sorted(fields)}) + + +class QbFieldArguments(t.TypedDict): + key: str + alias: t.Optional[str] + dtype: t.Optional[t.Any] + doc: str + is_attribute: bool + is_subscriptable: bool + + +def add_field( + key: str, + alias: t.Optional[str] = None, + *, + dtype: t.Optional[t.Any] = None, + doc: str = '', + is_attribute: bool = True, + is_subscriptable: bool = False, +) -> QbField: + """Add a `dtype`-dependent `QbField` representation of a field. + + :param key: The key of the field on the ORM entity + :param alias: The alias in the storage backend for the key, if not equal to ``key`` + :param dtype: The data type of the field. If None, the field is of variable type. + :param doc: A docstring for the field + :param is_attribute: If True, the ``backend_key`` property will prepend "attributes." to field name + :param is_subscriptable: If True, a new field can be created by ``field["subkey"]`` + """ + kwargs: QbFieldArguments = { + 'key': key, + 'alias': alias, + 'dtype': dtype, + 'doc': doc, + 'is_attribute': is_attribute, + 'is_subscriptable': is_subscriptable, + } + if not isidentifier(key): + raise ValueError(f'{key} is not a valid python identifier') + if not is_attribute and alias: + raise ValueError('only attribute fields may be aliased') + if not dtype: + return QbField(**kwargs) + root_type = extract_root_type(dtype) + if root_type in (int, float, datetime.datetime): + return QbNumericField(**kwargs) + elif root_type is list: + return QbArrayField(**kwargs) + elif root_type is str: + return QbStrField(**kwargs) + elif root_type is dict: + return QbDictField(**kwargs) + else: + return QbField(**kwargs) diff --git a/src/aiida/orm/groups.py b/src/aiida/orm/groups.py index 0dea119f16..56e2065e9b 100644 --- a/src/aiida/orm/groups.py +++ b/src/aiida/orm/groups.py @@ -17,7 +17,7 @@ from aiida.manage import get_manager from . import convert, entities, extras, users -from .fields import QbField +from .fields import add_field if TYPE_CHECKING: from importlib_metadata import EntryPoint @@ -107,15 +107,50 @@ class Group(entities.Entity['BackendGroup', GroupCollection]): __type_string: ClassVar[Optional[str]] - __qb_fields__ = ( - QbField('uuid', dtype=str, doc='The UUID of the group'), - QbField('type_string', dtype=str, doc='The type of the group'), - QbField('label', dtype=str, doc='The group label'), - QbField('description', dtype=str, doc='The group description'), - QbField('time', dtype=str, doc='The time of the group creation'), - QbField('extras', dtype=Dict[str, Any], doc='The group extras'), - QbField('user_pk', 'user_id', dtype=int, doc='The PK for the creating user'), - ) + __qb_fields__ = [ + add_field( + 'uuid', + dtype=str, + is_attribute=False, + doc='The UUID of the group', + ), + add_field( + 'type_string', + dtype=str, + is_attribute=False, + doc='The type of the group', + ), + add_field( + 'label', + dtype=str, + is_attribute=False, + doc='The group label', + ), + add_field( + 'description', + dtype=str, + is_attribute=False, + doc='The group description', + ), + add_field( + 'time', + dtype=str, + is_attribute=False, + doc='The time of the group creation', + ), + add_field( + 'extras', + dtype=Dict[str, Any], + is_attribute=False, + doc='The group extras', + ), + add_field( + 'user_pk', + dtype=int, + is_attribute=False, + doc='The PK for the creating user', + ), + ] _CLS_COLLECTION = GroupCollection diff --git a/src/aiida/orm/logs.py b/src/aiida/orm/logs.py index 68907ff3cc..a98814f82c 100644 --- a/src/aiida/orm/logs.py +++ b/src/aiida/orm/logs.py @@ -15,7 +15,7 @@ from aiida.manage import get_manager from . import entities -from .fields import QbField +from .fields import add_field if TYPE_CHECKING: from aiida.orm import Node @@ -128,15 +128,50 @@ class Log(entities.Entity['BackendLog', LogCollection]): _CLS_COLLECTION = LogCollection - __qb_fields__ = ( - QbField('uuid', dtype=str, doc='The UUID of the node'), - QbField('loggername', dtype=str, doc='The name of the logger'), - QbField('levelname', dtype=str, doc='The name of the log level'), - QbField('message', dtype=str, doc='The message of the log'), - QbField('time', dtype=datetime, doc='The time at which the log was created'), - QbField('metadata', dtype=Dict[str, Any], doc='The metadata of the log'), - QbField('node_pk', 'dbnode_id', dtype=int, doc='The PK for the node'), - ) + __qb_fields__ = [ + add_field( + 'uuid', + dtype=str, + is_attribute=False, + doc='The UUID of the node', + ), + add_field( + 'loggername', + dtype=str, + is_attribute=False, + doc='The name of the logger', + ), + add_field( + 'levelname', + dtype=str, + is_attribute=False, + doc='The name of the log level', + ), + add_field( + 'message', + dtype=str, + is_attribute=False, + doc='The message of the log', + ), + add_field( + 'time', + dtype=datetime, + is_attribute=False, + doc='The time at which the log was created', + ), + add_field( + 'metadata', + dtype=Dict[str, Any], + is_attribute=False, + doc='The metadata of the log', + ), + add_field( + 'node_pk', + dtype=int, + is_attribute=False, + doc='The PK for the node', + ), + ] def __init__( self, diff --git a/src/aiida/orm/nodes/data/array/bands.py b/src/aiida/orm/nodes/data/array/bands.py index 20861ef820..4d256f722e 100644 --- a/src/aiida/orm/nodes/data/array/bands.py +++ b/src/aiida/orm/nodes/data/array/bands.py @@ -17,7 +17,7 @@ from aiida.common.exceptions import ValidationError from aiida.common.utils import join_labels, prettify_labels -from aiida.orm.fields import QbAttrField +from aiida.orm.fields import add_field from .kpoints import KpointsData @@ -212,10 +212,18 @@ def nint(num): class BandsData(KpointsData): """Class to handle bands data""" - __qb_fields__ = ( - QbAttrField('array_labels', dtype=Optional[List[str]], doc='Labels associated with the band arrays'), - QbAttrField('units', dtype=str, doc='Units in which the data in bands were stored'), - ) + __qb_fields__ = [ + add_field( + 'array_labels', + dtype=Optional[List[str]], + doc='Labels associated with the band arrays', + ), + add_field( + 'units', + dtype=str, + doc='Units in which the data in bands were stored', + ), + ] def set_kpointsdata(self, kpointsdata): """Load the kpoints from a kpoint object. diff --git a/src/aiida/orm/nodes/data/array/kpoints.py b/src/aiida/orm/nodes/data/array/kpoints.py index 17242b610b..7a43ca9886 100644 --- a/src/aiida/orm/nodes/data/array/kpoints.py +++ b/src/aiida/orm/nodes/data/array/kpoints.py @@ -14,7 +14,7 @@ import numpy -from aiida.orm.fields import QbAttrField +from aiida.orm.fields import add_field from .array import ArrayData @@ -37,16 +37,48 @@ class KpointsData(ArrayData): set_cell_from_structure methods. """ - __qb_fields__ = ( - QbAttrField('labels', dtype=List[str], doc='Labels associated with the list of kpoints'), - QbAttrField('label_numbers', dtype=List[int], doc='Index of the labels in the list of kpoints'), - QbAttrField('mesh', dtype=List[int], doc='Mesh of kpoints'), - QbAttrField('offset', dtype=List[float], doc='Offset of kpoints'), - QbAttrField('cell', dtype=List[List[float]], doc='Unit cell of the crystal, in Angstroms'), - QbAttrField('pbc1', dtype=bool, doc='True if the first lattice vector is periodic'), - QbAttrField('pbc2', dtype=bool, doc='True if the second lattice vector is periodic'), - QbAttrField('pbc3', dtype=bool, doc='True if the third lattice vector is periodic'), - ) + __qb_fields__ = [ + add_field( + 'labels', + dtype=List[str], + doc='Labels associated with the list of kpoints', + ), + add_field( + 'label_numbers', + dtype=List[int], + doc='Index of the labels in the list of kpoints', + ), + add_field( + 'mesh', + dtype=List[int], + doc='Mesh of kpoints', + ), + add_field( + 'offset', + dtype=List[float], + doc='Offset of kpoints', + ), + add_field( + 'cell', + dtype=List[List[float]], + doc='Unit cell of the crystal, in Angstroms', + ), + add_field( + 'pbc1', + dtype=bool, + doc='True if the first lattice vector is periodic', + ), + add_field( + 'pbc2', + dtype=bool, + doc='True if the second lattice vector is periodic', + ), + add_field( + 'pbc3', + dtype=bool, + doc='True if the third lattice vector is periodic', + ), + ] def get_description(self): """Returns a string with infos retrieved from kpoints node's properties. diff --git a/src/aiida/orm/nodes/data/array/trajectory.py b/src/aiida/orm/nodes/data/array/trajectory.py index 7d26165da7..dd86f34b08 100644 --- a/src/aiida/orm/nodes/data/array/trajectory.py +++ b/src/aiida/orm/nodes/data/array/trajectory.py @@ -11,7 +11,7 @@ import collections.abc from typing import List -from aiida.orm.fields import QbAttrField +from aiida.orm.fields import add_field from .array import ArrayData @@ -23,11 +23,23 @@ class TrajectoryData(ArrayData): possibly with velocities). """ - __qb_fields__ = ( - QbAttrField('units_positions', 'units|positions', dtype=str), - QbAttrField('units_times', 'units|times', dtype=str), - QbAttrField('symbols', dtype=List[str], doc='list of symbols'), - ) + __qb_fields__ = [ + add_field( + 'units_positions', + 'units|positions', + dtype=str, + ), + add_field( + 'units_times', + 'units|times', + dtype=str, + ), + add_field( + 'symbols', + dtype=List[str], + doc='list of symbols', + ), + ] def __init__(self, structurelist=None, **kwargs): super().__init__(**kwargs) diff --git a/src/aiida/orm/nodes/data/base.py b/src/aiida/orm/nodes/data/base.py index ccf0d40fb4..4aecf7af9b 100644 --- a/src/aiida/orm/nodes/data/base.py +++ b/src/aiida/orm/nodes/data/base.py @@ -9,7 +9,7 @@ """`Data` sub class to be used as a base for data containers that represent base python data types.""" from functools import singledispatch -from aiida.orm.fields import QbAttrField +from aiida.orm.fields import add_field from .data import Data @@ -25,7 +25,12 @@ def to_aiida_type(value): class BaseType(Data): """`Data` sub class to be used as a base for data containers that represent base python data types.""" - __qb_fields__ = (QbAttrField('value', doc='The value of the data'),) + __qb_fields__ = [ + add_field( + 'value', + doc='The value of the data', + ), + ] def __init__(self, value=None, **kwargs): try: diff --git a/src/aiida/orm/nodes/data/cif.py b/src/aiida/orm/nodes/data/cif.py index 0e59a0fbdd..ad8fdc7827 100644 --- a/src/aiida/orm/nodes/data/cif.py +++ b/src/aiida/orm/nodes/data/cif.py @@ -11,7 +11,7 @@ from typing import List from aiida.common.utils import Capturing -from aiida.orm.fields import QbAttrField +from aiida.orm.fields import add_field from .singlefile import SinglefileData @@ -249,11 +249,20 @@ class CifData(SinglefileData): _values = None _ase = None - __qb_fields__ = ( - QbAttrField('formulae', dtype=List[str]), - QbAttrField('spacegroup_numbers', dtype=List[str]), - QbAttrField('md5', dtype=str), - ) + __qb_fields__ = [ + add_field( + 'formulae', + dtype=List[str], + ), + add_field( + 'spacegroup_numbers', + dtype=List[str], + ), + add_field( + 'md5', + dtype=str, + ), + ] def __init__(self, ase=None, file=None, filename=None, values=None, scan_type=None, parse_policy=None, **kwargs): """Construct a new instance and set the contents to that of the file. diff --git a/src/aiida/orm/nodes/data/code/legacy.py b/src/aiida/orm/nodes/data/code/legacy.py index 676702203f..377641c88c 100644 --- a/src/aiida/orm/nodes/data/code/legacy.py +++ b/src/aiida/orm/nodes/data/code/legacy.py @@ -15,7 +15,7 @@ from aiida.common.log import override_log_level from aiida.common.warnings import warn_deprecation from aiida.orm import Computer -from aiida.orm.fields import QbAttrField +from aiida.orm.fields import add_field from .abstract import AbstractCode @@ -38,22 +38,38 @@ class Code(AbstractCode): for the code to be run). """ - __qb_fields__ = ( - QbAttrField( + __qb_fields__ = [ + add_field( 'prepend_text', dtype=Optional[str], doc='The code that will be put in the scheduler script before the execution of the code', ), - QbAttrField( + add_field( 'append_text', dtype=Optional[str], doc='The code that will be put in the scheduler script after the execution of the code', ), - QbAttrField('input_plugin', dtype=Optional[str], doc='The name of the input plugin to be used for this code'), - QbAttrField('local_executable', dtype=Optional[str], doc='Path to a local executable'), - QbAttrField('remote_exec_path', dtype=Optional[str], doc='Remote path to executable'), - QbAttrField('is_local', dtype=Optional[bool], doc='Whether the code is local or remote'), - ) + add_field( + 'input_plugin', + dtype=Optional[str], + doc='The name of the input plugin to be used for this code', + ), + add_field( + 'local_executable', + dtype=Optional[str], + doc='Path to a local executable', + ), + add_field( + 'remote_exec_path', + dtype=Optional[str], + doc='Remote path to executable', + ), + add_field( + 'is_local', + dtype=Optional[bool], + doc='Whether the code is local or remote', + ), + ] def __init__(self, remote_computer_exec=None, local_executable=None, input_plugin_name=None, files=None, **kwargs): super().__init__(**kwargs) diff --git a/src/aiida/orm/nodes/data/data.py b/src/aiida/orm/nodes/data/data.py index d747e1d58e..084f242e9a 100644 --- a/src/aiida/orm/nodes/data/data.py +++ b/src/aiida/orm/nodes/data/data.py @@ -7,13 +7,13 @@ # For further information please visit http://www.aiida.net # ########################################################################### """Module with `Node` sub class `Data` to be used as a base class for data structures.""" -from typing import Dict, Optional, Sequence +from typing import Dict, Optional from aiida.common import exceptions from aiida.common.lang import override from aiida.common.links import LinkType from aiida.orm.entities import from_backend_entity -from aiida.orm.fields import QbAttrField, QbField +from aiida.orm.fields import add_field from ..node import Node @@ -45,9 +45,14 @@ class Data(Node): _storable = True _unstorable_message = 'storing for this node has been disabled' - __qb_fields__: Sequence[QbField] = ( - QbAttrField('source', dtype=Optional[dict], subscriptable=True, doc='Source of the data'), - ) + __qb_fields__ = [ + add_field( + 'source', + dtype=Optional[dict], + is_subscriptable=True, + doc='Source of the data', + ), + ] def __init__(self, *args, source=None, **kwargs): """Construct a new instance, setting the ``source`` attribute if provided as a keyword argument.""" diff --git a/src/aiida/orm/nodes/data/dict.py b/src/aiida/orm/nodes/data/dict.py index e1eb25e25a..dfd4f1c47a 100644 --- a/src/aiida/orm/nodes/data/dict.py +++ b/src/aiida/orm/nodes/data/dict.py @@ -14,7 +14,7 @@ from typing import Dict as DictType from aiida.common import exceptions -from aiida.orm.fields import QbField +from aiida.orm.fields import add_field from .base import to_aiida_type from .data import Data @@ -50,9 +50,15 @@ class Dict(Data): Finally, all dictionary mutations will be forbidden once the node is stored. """ - __qb_fields__ = ( - QbField('dict', 'attributes', dtype=DictType[str, Any], subscriptable=True, doc='Source of the data'), - ) + __qb_fields__ = [ + add_field( + 'dict', + dtype=DictType[str, Any], + is_attribute=False, + is_subscriptable=True, + doc='Source of the data', + ), + ] def __init__(self, value=None, **kwargs): """Initialise a ``Dict`` node instance. diff --git a/src/aiida/orm/nodes/data/remote/base.py b/src/aiida/orm/nodes/data/remote/base.py index 7655f52dba..6a9a1b54d8 100644 --- a/src/aiida/orm/nodes/data/remote/base.py +++ b/src/aiida/orm/nodes/data/remote/base.py @@ -10,7 +10,7 @@ import os from aiida.orm import AuthInfo -from aiida.orm.fields import QbAttrField +from aiida.orm.fields import add_field from ..data import Data @@ -24,7 +24,12 @@ class RemoteData(Data): """ KEY_EXTRA_CLEANED = 'cleaned' - __qb_fields__ = (QbAttrField('remote_path', dtype=str),) + __qb_fields__ = [ + add_field( + 'remote_path', + dtype=str, + ), + ] def __init__(self, remote_path=None, **kwargs): super().__init__(**kwargs) diff --git a/src/aiida/orm/nodes/data/remote/stash/base.py b/src/aiida/orm/nodes/data/remote/stash/base.py index c6b7dd4a6b..27c8ddf245 100644 --- a/src/aiida/orm/nodes/data/remote/stash/base.py +++ b/src/aiida/orm/nodes/data/remote/stash/base.py @@ -1,9 +1,8 @@ """Data plugin that models an archived folder on a remote computer.""" -from typing import Sequence from aiida.common.datastructures import StashMode from aiida.common.lang import type_check -from aiida.orm.fields import QbAttrField, QbField +from aiida.orm.fields import add_field from ...data import Data @@ -29,9 +28,13 @@ class RemoteStashData(Data): _storable = False - __qb_fields__: Sequence[QbField] = ( - QbAttrField('stash_mode', dtype=str, doc='The mode with which the data was stashed'), - ) + __qb_fields__ = [ + add_field( + 'stash_mode', + dtype=str, + doc='The mode with which the data was stashed', + ), + ] def __init__(self, stash_mode: StashMode, **kwargs): """Construct a new instance diff --git a/src/aiida/orm/nodes/data/remote/stash/folder.py b/src/aiida/orm/nodes/data/remote/stash/folder.py index dca64e97a3..3a363ba978 100644 --- a/src/aiida/orm/nodes/data/remote/stash/folder.py +++ b/src/aiida/orm/nodes/data/remote/stash/folder.py @@ -3,7 +3,7 @@ from aiida.common.datastructures import StashMode from aiida.common.lang import type_check -from aiida.orm.fields import QbAttrField +from aiida.orm.fields import add_field from .base import RemoteStashData @@ -18,10 +18,18 @@ class RemoteStashFolderData(RemoteStashData): _storable = True - __qb_fields__ = ( - QbAttrField('target_basepath', dtype=str, doc='The the target basepath'), - QbAttrField('source_list', dtype=List[str], doc='The list of source files that were stashed'), - ) + __qb_fields__ = [ + add_field( + 'target_basepath', + dtype=str, + doc='The the target basepath', + ), + add_field( + 'source_list', + dtype=List[str], + doc='The list of source files that were stashed', + ), + ] def __init__(self, stash_mode: StashMode, target_basepath: str, source_list: List, **kwargs): """Construct a new instance diff --git a/src/aiida/orm/nodes/data/structure.py b/src/aiida/orm/nodes/data/structure.py index 8775ec324f..d2489e2e23 100644 --- a/src/aiida/orm/nodes/data/structure.py +++ b/src/aiida/orm/nodes/data/structure.py @@ -17,7 +17,7 @@ from aiida.common.constants import elements from aiida.common.exceptions import UnsupportedSpeciesError -from aiida.orm.fields import QbAttrField +from aiida.orm.fields import add_field from .data import Data @@ -695,14 +695,38 @@ class StructureData(Data): _dimensionality_label = {0: '', 1: 'length', 2: 'surface', 3: 'volume'} _internal_kind_tags = None - __qb_fields__ = ( - QbAttrField('pbc1', dtype=bool, doc='Whether periodic in the a direction'), - QbAttrField('pbc2', dtype=bool, doc='Whether periodic in the b direction'), - QbAttrField('pbc3', dtype=bool, doc='Whether periodic in the c direction'), - QbAttrField('cell', dtype=List[List[float]], doc='The cell parameters'), - QbAttrField('kinds', dtype=Optional[List[dict]], doc='The kinds of atoms'), - QbAttrField('sites', dtype=Optional[List[dict]], doc='The atomic sites'), - ) + __qb_fields__ = [ + add_field( + 'pbc1', + dtype=bool, + doc='Whether periodic in the a direction', + ), + add_field( + 'pbc2', + dtype=bool, + doc='Whether periodic in the b direction', + ), + add_field( + 'pbc3', + dtype=bool, + doc='Whether periodic in the c direction', + ), + add_field( + 'cell', + dtype=List[List[float]], + doc='The cell parameters', + ), + add_field( + 'kinds', + dtype=Optional[List[dict]], + doc='The kinds of atoms', + ), + add_field( + 'sites', + dtype=Optional[List[dict]], + doc='The atomic sites', + ), + ] def __init__( self, cell=None, pbc=None, ase=None, pymatgen=None, pymatgen_structure=None, pymatgen_molecule=None, **kwargs diff --git a/src/aiida/orm/nodes/node.py b/src/aiida/orm/nodes/node.py index 59fe1f996a..06afdf2a5b 100644 --- a/src/aiida/orm/nodes/node.py +++ b/src/aiida/orm/nodes/node.py @@ -10,7 +10,7 @@ from datetime import datetime from functools import cached_property from logging import Logger -from typing import TYPE_CHECKING, Any, ClassVar, Dict, Generic, Iterator, List, Optional, Sequence, Tuple, Type, TypeVar +from typing import TYPE_CHECKING, Any, ClassVar, Dict, Generic, Iterator, List, Optional, Tuple, Type, TypeVar from uuid import UUID from aiida.common import exceptions @@ -28,7 +28,7 @@ from ..entities import Collection as EntityCollection from ..entities import Entity, from_backend_entity from ..extras import EntityExtras -from ..fields import QbField +from ..fields import add_field from ..querybuilder import QueryBuilder from ..users import User from .attributes import NodeAttributes @@ -185,19 +185,71 @@ def _query_type_string(cls) -> str: # noqa: N805 _storable = False _unstorable_message = 'only Data, WorkflowNode, CalculationNode or their subclasses can be stored' - __qb_fields__: Sequence[QbField] = ( - QbField('uuid', dtype=str, doc='The UUID of the node'), - QbField('label', dtype=str, doc='The node label'), - QbField('description', dtype=str, doc='The node description'), - QbField('node_type', dtype=str, doc='The type of the node'), - QbField('ctime', dtype=datetime, doc='The creation time of the node'), - QbField('mtime', dtype=datetime, doc='The modification time of the node'), - QbField('repository_metadata', dtype=Dict[str, Any], doc='The repository virtual file system'), - QbField('extras', dtype=Dict[str, Any], subscriptable=True, doc='The node extras'), - QbField('user_pk', 'user_id', dtype=int, doc='The PK of the user who owns the node'), + __qb_fields__ = [ + add_field( + 'uuid', + dtype=str, + is_attribute=False, + doc='The UUID of the node', + ), + add_field( + 'label', + dtype=str, + is_attribute=False, + doc='The node label', + ), + add_field( + 'description', + dtype=str, + is_attribute=False, + doc='The node description', + ), + add_field( + 'node_type', + dtype=str, + is_attribute=False, + doc='The type of the node', + ), + add_field( + 'ctime', + dtype=datetime, + is_attribute=False, + doc='The creation time of the node', + ), + add_field( + 'mtime', + dtype=datetime, + is_attribute=False, + doc='The modification time of the node', + ), + add_field( + 'repository_metadata', + dtype=Dict[str, Any], + is_attribute=False, + doc='The repository virtual file system', + ), + add_field( + 'extras', + dtype=Dict[str, Any], + is_attribute=False, + is_subscriptable=True, + doc='The node extras', + ), + add_field( + 'user_pk', + dtype=int, + is_attribute=False, + doc='The PK of the user who owns the node', + ), # Subclasses denote specific keys in the attributes dict - # QbField('attributes', dtype=Dict[str, Any], subscriptable=True, doc='The node attributes'), - ) + add_field( + 'attributes', + dtype=Dict[str, Any], + is_attribute=False, + is_subscriptable=True, + doc='The node attributes', + ), + ] def __init__( self, diff --git a/src/aiida/orm/nodes/process/calculation/calcjob.py b/src/aiida/orm/nodes/process/calculation/calcjob.py index d8c184f6d8..006726fa9d 100644 --- a/src/aiida/orm/nodes/process/calculation/calcjob.py +++ b/src/aiida/orm/nodes/process/calculation/calcjob.py @@ -14,7 +14,7 @@ from aiida.common.datastructures import CalcJobState from aiida.common.lang import classproperty from aiida.common.links import LinkType -from aiida.orm.fields import QbAttrField +from aiida.orm.fields import add_field from ..process import ProcessNodeCaching from .calculation import CalculationNode @@ -78,32 +78,58 @@ class CalcJobNode(CalculationNode): SCHEDULER_LAST_JOB_INFO_KEY = 'last_job_info' SCHEDULER_DETAILED_JOB_INFO_KEY = 'detailed_job_info' - __qb_fields__ = ( - QbAttrField(SCHEDULER_STATE_KEY, dtype=Optional[str], doc='The state of the scheduler'), - QbAttrField(CALC_JOB_STATE_KEY, dtype=Optional[str], doc='The active state of the calculation job'), - QbAttrField(REMOTE_WORKDIR_KEY, dtype=Optional[str], doc='The path to the remote (on cluster) scratch folder'), - QbAttrField(SCHEDULER_JOB_ID_KEY, dtype=Optional[str], doc='The scheduler job id'), - QbAttrField( + __qb_fields__ = [ + add_field( + SCHEDULER_STATE_KEY, + dtype=Optional[str], + doc='The state of the scheduler', + ), + add_field( + CALC_JOB_STATE_KEY, + dtype=Optional[str], + doc='The active state of the calculation job', + ), + add_field( + REMOTE_WORKDIR_KEY, + dtype=Optional[str], + doc='The path to the remote (on cluster) scratch folder', + ), + add_field( + SCHEDULER_JOB_ID_KEY, + dtype=Optional[str], + doc='The scheduler job id', + ), + add_field( SCHEDULER_LAST_CHECK_TIME_KEY, dtype=Optional[str], doc='The last time the scheduler was checked, in isoformat', ), - QbAttrField( - SCHEDULER_LAST_JOB_INFO_KEY, dtype=Optional[str], doc='The last job info returned by the scheduler' + add_field( + SCHEDULER_LAST_JOB_INFO_KEY, + dtype=Optional[str], + doc='The last job info returned by the scheduler', ), - QbAttrField( - SCHEDULER_DETAILED_JOB_INFO_KEY, dtype=Optional[dict], doc='The detailed job info returned by the scheduler' + add_field( + SCHEDULER_DETAILED_JOB_INFO_KEY, + dtype=Optional[dict], + doc='The detailed job info returned by the scheduler', ), - QbAttrField( - RETRIEVE_LIST_KEY, dtype=Optional[List[str]], doc='The list of files to retrieve from the remote cluster' + add_field( + RETRIEVE_LIST_KEY, + dtype=Optional[List[str]], + doc='The list of files to retrieve from the remote cluster', ), - QbAttrField( + add_field( RETRIEVE_TEMPORARY_LIST_KEY, dtype=Optional[List[str]], doc='The list of temporary files to retrieve from the remote cluster', ), - QbAttrField(IMMIGRATED_KEY, dtype=Optional[bool], doc='Whether the node has been migrated'), - ) + add_field( + IMMIGRATED_KEY, + dtype=Optional[bool], + doc='Whether the node has been migrated', + ), + ] # An optional entry point for a CalculationTools instance _tools = None diff --git a/src/aiida/orm/nodes/process/process.py b/src/aiida/orm/nodes/process/process.py index 9d3cf78eb3..0675cd0fb3 100644 --- a/src/aiida/orm/nodes/process/process.py +++ b/src/aiida/orm/nodes/process/process.py @@ -8,14 +8,14 @@ ########################################################################### """Module with `Node` sub class for processes.""" import enum -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Tuple, Type, Union +from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Type, Union from plumpy.process_states import ProcessState from aiida.common import exceptions from aiida.common.lang import classproperty from aiida.common.links import LinkType -from aiida.orm.fields import QbAttrField, QbField +from aiida.orm.fields import add_field from aiida.orm.utils.mixins import Sealable from ..caching import NodeCaching @@ -182,17 +182,53 @@ def _updatable_attributes(cls) -> Tuple[str, ...]: # noqa: N805 cls.PROCESS_STATUS_KEY, ) - __qb_fields__: Sequence[QbField] = ( - QbField('process_type', dtype=Optional[str], doc='The process type string'), - QbField('computer_pk', 'dbcomputer_id', dtype=Optional[int], doc='The computer PK'), - QbAttrField(PROCESS_LABEL_KEY, dtype=Optional[str], doc='The process label'), - QbAttrField(PROCESS_STATE_KEY, dtype=Optional[str], doc='The process state enum'), - QbAttrField(PROCESS_STATUS_KEY, dtype=Optional[str], doc='The process status is a generic status message'), - QbAttrField(EXIT_STATUS_KEY, dtype=Optional[int], doc='The process exit status'), - QbAttrField(EXIT_MESSAGE_KEY, dtype=Optional[str], doc='The process exit message'), - QbAttrField(EXCEPTION_KEY, dtype=Optional[str], doc='The process exception message'), - QbAttrField(PROCESS_PAUSED_KEY, dtype=bool, doc='Whether the process is paused'), - ) + __qb_fields__ = [ + add_field( + 'process_type', + dtype=Optional[str], + doc='The process type string', + ), + add_field( + 'computer_pk', + dtype=Optional[int], + doc='The computer PK', + ), + add_field( + PROCESS_LABEL_KEY, + dtype=Optional[str], + doc='The process label', + ), + add_field( + PROCESS_STATE_KEY, + dtype=Optional[str], + doc='The process state enum', + ), + add_field( + PROCESS_STATUS_KEY, + dtype=Optional[str], + doc='The process status is a generic status message', + ), + add_field( + EXIT_STATUS_KEY, + dtype=Optional[int], + doc='The process exit status', + ), + add_field( + EXIT_MESSAGE_KEY, + dtype=Optional[str], + doc='The process exit message', + ), + add_field( + EXCEPTION_KEY, + dtype=Optional[str], + doc='The process exception message', + ), + add_field( + PROCESS_PAUSED_KEY, + dtype=bool, + doc='Whether the process is paused', + ), + ] def set_metadata_inputs(self, value: Dict[str, Any]) -> None: """Set the mapping of inputs corresponding to ``metadata`` ports that were passed to the process.""" diff --git a/src/aiida/orm/querybuilder.py b/src/aiida/orm/querybuilder.py index 0565404ebb..6f21f5a2b0 100644 --- a/src/aiida/orm/querybuilder.py +++ b/src/aiida/orm/querybuilder.py @@ -646,7 +646,7 @@ def order_by(self, order_by: OrderByType) -> 'QueryBuilder': if isinstance(item_to_order_by, str): item_to_order_by = {item_to_order_by: {}} # noqa: PLW2901 elif isinstance(item_to_order_by, fields.QbField): - item_to_order_by = {item_to_order_by.qb_field: {}} # noqa: PLW2901 + item_to_order_by = {item_to_order_by.backend_key: {}} # noqa: PLW2901 elif isinstance(item_to_order_by, dict): pass else: @@ -715,23 +715,18 @@ def add_filter(self, tagspec: Union[str, EntityClsType], filter_spec: FilterType @staticmethod def _process_filters(filters: FilterType) -> Dict[str, Any]: """Process filters.""" - filters_dict: Dict[Union[str, fields.QbField], Any] = {} - if isinstance(filters, fields.QbFieldFilters): - filters_dict = filters.as_dict() # type: ignore[assignment] - elif isinstance(filters, dict): - filters_dict = filters # type: ignore[assignment] - else: - raise TypeError('Filters have to be passed as dictionaries or QbFieldFilters') + if not isinstance(filters, (dict, fields.QbFieldFilters)): + raise TypeError('Filters must be either a dictionary or QbFieldFilters') processed_filters = {} - for key, value in filters_dict.items(): + for key, value in filters.items(): if isinstance(value, entities.Entity): # Convert to be the id of the joined entity because we can't query # for the object instance directly processed_filters[f'{key}_id'] = value.pk elif isinstance(key, fields.QbField): - processed_filters[key.qb_field] = value + processed_filters[key.backend_key] = value else: processed_filters[key] = value @@ -846,10 +841,10 @@ def add_projection(self, tag_spec: Union[str, EntityClsType], projection_spec: P def _update_project_map(projection: fields.QbField): """Return the DB field to use, or a tuple of the DB field to use and the key to return.""" - if projection.qb_field != projection.key: + if projection.backend_key != projection.key: self._project_map.setdefault(tag, {}) - self._project_map[tag][projection.qb_field] = projection.key - return projection.qb_field + self._project_map[tag][projection.backend_key] = projection.key + return projection.backend_key if not isinstance(projection_spec, (list, tuple)): projection_spec = [projection_spec] # type: ignore[list-item] diff --git a/src/aiida/orm/users.py b/src/aiida/orm/users.py index 28630a78af..d9910c67ad 100644 --- a/src/aiida/orm/users.py +++ b/src/aiida/orm/users.py @@ -13,7 +13,7 @@ from aiida.manage import get_manager from . import entities -from .fields import QbField +from .fields import add_field if TYPE_CHECKING: from aiida.orm.implementation import StorageBackend @@ -52,12 +52,32 @@ class User(entities.Entity['BackendUser', UserCollection]): _CLS_COLLECTION = UserCollection - __qb_fields__ = ( - QbField('email', dtype=str, doc='The user email'), - QbField('first_name', dtype=str, doc='The user first name'), - QbField('last_name', dtype=str, doc='The user last name'), - QbField('institution', dtype=str, doc='The user institution'), - ) + __qb_fields__ = [ + add_field( + 'email', + dtype=str, + is_attribute=False, + doc='The user email', + ), + add_field( + 'first_name', + dtype=str, + is_attribute=False, + doc='The user first name', + ), + add_field( + 'last_name', + dtype=str, + is_attribute=False, + doc='The user last name', + ), + add_field( + 'institution', + dtype=str, + is_attribute=False, + doc='The user institution', + ), + ] def __init__( self, diff --git a/src/aiida/orm/utils/mixins.py b/src/aiida/orm/utils/mixins.py index e9fe60e2ec..aa6d68c1d0 100644 --- a/src/aiida/orm/utils/mixins.py +++ b/src/aiida/orm/utils/mixins.py @@ -14,7 +14,7 @@ from aiida.common import exceptions from aiida.common.lang import classproperty, override, type_check from aiida.common.warnings import warn_deprecation -from aiida.orm.fields import QbAttrField +from aiida.orm.fields import add_field class FunctionCalculationMixin: @@ -180,7 +180,13 @@ class Sealable: SEALED_KEY = 'sealed' - __qb_fields__ = (QbAttrField(SEALED_KEY, dtype=bool, doc='Whether the node is sealed'),) + __qb_fields__ = [ + add_field( + SEALED_KEY, + dtype=bool, + doc='Whether the node is sealed', + ), + ] @classproperty def _updatable_attributes(cls) -> tuple[str, ...]: # noqa: N805 diff --git a/src/aiida/storage/psql_dos/orm/querybuilder/main.py b/src/aiida/storage/psql_dos/orm/querybuilder/main.py index 0bbd65c8b9..410ddd1a96 100644 --- a/src/aiida/storage/psql_dos/orm/querybuilder/main.py +++ b/src/aiida/storage/psql_dos/orm/querybuilder/main.py @@ -39,6 +39,36 @@ jsonb_array_length = sa_func.jsonb_array_length array_length = sa_func.array_length +PROJECT_MAP = { + 'db_dbauthinfo': { + 'pk': 'id', + 'computer_pk': 'dbcomputer_id', + 'user_pk': 'aiidauser_id', + }, + 'db_dbnode': { + 'pk': 'id', + 'dict': 'attributes', + 'computer_pk': 'dbcomputer_id', + 'user_pk': 'user_id', + }, + 'db_dbcomputer': { + 'pk': 'id', + }, + 'db_dbgroup': { + 'pk': 'id', + 'user_pk': 'user_id', + }, + 'db_dbcomment': { + 'pk': 'id', + 'user_pk': 'user_id', + 'node_pk': 'dbnode_id', + }, + 'db_dblog': { + 'pk': 'id', + 'node_pk': 'dbnode_id', + }, +} + @dataclass class BuiltQuery: @@ -398,7 +428,7 @@ def build_filters(self, alias: AliasedClass, filter_spec: Dict[str, Any]) -> Opt column_name = path_spec.split('.')[0] attr_key = path_spec.split('.')[1:] - is_jsonb = bool(attr_key) or column_name in ('attributes', 'extras') + is_jsonb = bool(attr_key) or column_name in ('dict', 'attributes', 'extras') column: Optional[InstrumentedAttribute] try: column = get_column(column_name, alias) @@ -838,6 +868,9 @@ def modify_expansions( def get_column(colname: str, alias: AliasedClass) -> InstrumentedAttribute: """Return the column for a given projection.""" + table_name = get_table_name(alias) + if projections := PROJECT_MAP.get(table_name): + colname = projections.get(colname, colname) try: return getattr(alias, colname) except AttributeError as exc: diff --git a/tests/orm/test_fields.py b/tests/orm/test_fields.py index 1b77803256..7126c6d405 100644 --- a/tests/orm/test_fields.py +++ b/tests/orm/test_fields.py @@ -6,25 +6,37 @@ # For further information on the license, see the LICENSE.txt file # # For further information please visit http://www.aiida.net # ########################################################################### -# pylint: disable=missing-class-docstring,protected-access,unused-argument """Test for entity fields""" + import pytest from aiida import orm -from aiida.orm import Data, Dict, QueryBuilder, fields +from aiida.orm.fields import add_field from importlib_metadata import entry_points EPS = entry_points() -@pytest.mark.parametrize('entity_cls', (orm.AuthInfo, orm.Comment, orm.Computer, orm.Group, orm.Log, orm.User)) +@pytest.mark.parametrize( + 'entity_cls', + (orm.AuthInfo, orm.Comment, orm.Computer, orm.Group, orm.Log, orm.User), +) def test_all_entity_fields(entity_cls, data_regression): data_regression.check( - {key: repr(value) for key, value in entity_cls.fields._dict.items()}, basename=f'fields_{entity_cls.__name__}' + {key: repr(value) for key, value in entity_cls.fields._dict.items()}, + basename=f'fields_{entity_cls.__name__}', ) @pytest.mark.parametrize( - 'group,name', ((group, name) for group in ('aiida.node', 'aiida.data') for name in EPS.select(group=group).names) + 'group,name', + ( + (group, name) + for group in ( + 'aiida.node', + 'aiida.data', + ) + for name in EPS.select(group=group).names + ), ) def test_all_node_fields(group, name, data_regression): """Test that all the node fields are correctly registered.""" @@ -35,6 +47,44 @@ def test_all_node_fields(group, name, data_regression): ) +def test_add_field(): + """Test the `add_field` API.""" + + class NewNode(orm.Data): + __qb_fields__ = ( + add_field( + 'key1', + dtype=str, + is_subscriptable=False, + ), + ) + + node = NewNode() + + assert 'key1' in node.fields + assert node.fields.key1.dtype is str + assert isinstance(node.fields.key1, orm.fields.QbStrField) + assert node.fields.key1.backend_key == 'attributes.key1' + assert not node.fields.key1.is_subscriptable + + +@pytest.mark.parametrize('key', ('|', 'some.field', '1key')) +def test_invalid_field_keys(key): + """Test for invalid field keys.""" + with pytest.raises(ValueError): + _ = add_field(key) + + +def test_disallowed_alias_for_db_field(): + """Test for disallowed alias argument for database fields.""" + with pytest.raises(ValueError): + _ = add_field( + 'some_key', + 'alias_not_allowed_for_db_fields', + is_attribute=False, + ) + + def test_query_new_class(clear_database_before_test, monkeypatch): """Test that fields are correctly registered on a new data class, and can be used in a query. @@ -44,77 +94,128 @@ def test_query_new_class(clear_database_before_test, monkeypatch): def _dummy(*args, **kwargs): return True - monkeypatch.setattr(plugins.entry_point, 'is_registered_entry_point', _dummy) + monkeypatch.setattr( + plugins.entry_point, + 'is_registered_entry_point', + _dummy, + ) - class NewNode(Data): - __qb_fields__ = ( - fields.QbField('key1', 'attributes.key1'), - fields.QbAttrField('key2'), - fields.QbAttrField('key3'), - ) + class NewNode(orm.Data): + __qb_fields__ = [ + add_field('some_label', dtype=str), + add_field('some_value', dtype=int), + ] node = NewNode() - node.set_attribute_many({'key1': 2, 'key2': 2, 'key3': 3}) + node.base.attributes.set_many({'some_label': 'A', 'some_value': 1}) node.store() node = NewNode() - node.set_attribute_many({'key1': 1, 'key2': 2, 'key3': 1}) + node.base.attributes.set_many({'some_label': 'B', 'some_value': 2}) node.store() node = NewNode() - node.set_attribute_many({'key1': 4, 'key2': 5, 'key3': 6}) + node.base.attributes.set_many({'some_label': 'C', 'some_value': 3}) node.store() result = ( - QueryBuilder() + orm.QueryBuilder() .append( NewNode, tag='node', - project=[NewNode.fields.key1, NewNode.fields.key2, NewNode.fields.key3], - filters={NewNode.fields.key2: 2}, + project=[ + NewNode.fields.some_label, + NewNode.fields.some_value, + ], + filters=NewNode.fields.some_value > 1, ) .order_by({'node': NewNode.fields.ctime}) .all() ) - assert result == [[2, 2, 3], [1, 2, 1]] + assert result == [['B', 2], ['C', 3]] def test_filter_operators(): """Test that the operators are correctly registered.""" - field = Data.fields.pk - filters = (field == 1) & (field != 2) & (field > 3) & (field >= 4) & (field < 5) & (field <= 6) + pk = orm.Data.fields.pk + filters = (pk == 1) & (pk != 2) & (pk > 3) & (pk >= 4) & (pk < 5) & (pk <= 6) & ~(pk == 7) & ~(pk < 8) # print(filters.as_dict()) assert filters.as_dict() == { - fields.QbField('pk', qb_field='id', dtype=int): { - 'and': [{'==': 1}, {'!=': 2}, {'>': 3}, {'>=': 4}, {'<': 5}, {'<=': 6}] - } + 'and': [ + {'pk': {'==': 1}}, + {'pk': {'!==': 2}}, + {'pk': {'>': 3}}, + {'pk': {'>=': 4}}, + {'pk': {'<': 5}}, + {'pk': {'<=': 6}}, + {'pk': {'!==': 7}}, + {'pk': {'!<': 8}}, + ] } def test_filter_comparators(): """Test that the comparators are correctly registered.""" - field = Data.fields.uuid - filters = (field.in_(['a'])) & (field.not_in(['b'])) & (field.like('a%')) & (field.ilike('a%')) - print(filters.as_dict()) + field = orm.Data.fields.attributes['something'] + filters = ( + (field.in_(['a'])) & ~(field.in_(['b'])) + | (field.like('a%')) & (field.ilike('a%')) + | ~((field.contains(['a'])) & (field.shorter(3))) + ) assert filters.as_dict() == { - fields.QbField('uuid', qb_field='uuid', dtype=str): { - 'and': [{'in': {'a'}}, {'!in': {'b'}}, {'like': 'a%'}, {'ilike': 'a%'}] - } + 'or': [ + { + 'and': [ + {'attributes.something': {'in': ['a']}}, + {'attributes.something': {'!in': ['b']}}, + ] + }, + { + 'and': [ + {'attributes.something': {'like': 'a%'}}, + {'attributes.something': {'ilike': 'a%'}}, + ] + }, + { + '!and': [ + {'attributes.something': {'contains': ['a']}}, + {'attributes.something': {'shorter': 3}}, + ] + }, + ] } def test_query_filters(clear_database_before_test): """Test using fields to generate a query filter.""" - node1 = Data().store() - Data().store() - filters = (Data.fields.pk == node1.pk) & (Data.fields.pk >= node1.pk) - result = QueryBuilder().append(Data, project=Data.fields.pk, filters=filters).all() - assert result == [[node1.pk]] + node = orm.Data().store() + orm.Data().store() + filters = (orm.Data.fields.pk == node.pk) & (orm.Data.fields.pk >= node.pk) + result = ( + orm.QueryBuilder() + .append( + orm.Data, + project=orm.Data.fields.pk, + filters=filters, + ) + .all() + ) + assert result == [[node.pk]] def test_query_subscriptable(clear_database_before_test): """Test using subscriptable fields in a query.""" - node = Dict(dict={'a': 1}).store() - node.set_extra('b', 2) - result = QueryBuilder().append(Dict, project=[Dict.fields.dict['a'], Dict.fields.extras['b']]).all() + node = orm.Dict(dict={'a': 1}).store() + node.base.extras.set('b', 2) + result = ( + orm.QueryBuilder() + .append( + orm.Dict, + project=[ + orm.Dict.fields.dict['a'], + orm.Dict.fields.extras['b'], + ], + ) + .all() + ) assert result == [[1, 2]] diff --git a/tests/orm/test_fields/fields_AuthInfo.yml b/tests/orm/test_fields/fields_AuthInfo.yml index f0f7eedb2f..7f7e4473ac 100644 --- a/tests/orm/test_fields/fields_AuthInfo.yml +++ b/tests/orm/test_fields/fields_AuthInfo.yml @@ -1,6 +1,6 @@ -auth_params: QbField('auth_params', dtype=typing.Dict[str, typing.Any]) -computer_pk: QbField('computer_pk', 'dbcomputer_id', dtype=int) -enabled: QbField('enabled', dtype=bool) -metadata: QbField('metadata', dtype=typing.Dict[str, typing.Any]) -pk: QbField('pk', 'id', dtype=int) -user_pk: QbField('user_pk', 'aiidauser_id', dtype=int) +auth_params: QbDictField('auth_params', dtype=Dict[str, Any], is_attribute=False) +computer_pk: QbNumericField('computer_pk', dtype=int, is_attribute=False) +enabled: QbField('enabled', dtype=bool, is_attribute=False) +metadata: QbDictField('metadata', dtype=Dict[str, Any], is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) diff --git a/tests/orm/test_fields/fields_Comment.yml b/tests/orm/test_fields/fields_Comment.yml index 3806a245a0..727563a907 100644 --- a/tests/orm/test_fields/fields_Comment.yml +++ b/tests/orm/test_fields/fields_Comment.yml @@ -1,7 +1,7 @@ -content: QbField('content', dtype=str) -ctime: QbField('ctime', dtype=datetime) -mtime: QbField('mtime', dtype=datetime) -node_pk: QbField('node_pk', 'dbnode_id', dtype=int) -pk: QbField('pk', 'id', dtype=int) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +content: QbStrField('content', dtype=str, is_attribute=False) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_pk: QbNumericField('node_pk', dtype=int, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_Computer.yml b/tests/orm/test_fields/fields_Computer.yml index 72e6c4656a..bfc4d20ad5 100644 --- a/tests/orm/test_fields/fields_Computer.yml +++ b/tests/orm/test_fields/fields_Computer.yml @@ -1,8 +1,8 @@ -description: QbField('description', dtype=str) -hostname: QbField('hostname', dtype=str) -label: QbField('label', dtype=str) -metadata: QbField('metadata', dtype=typing.Dict[str, typing.Any]) -pk: QbField('pk', 'id', dtype=int) -scheduler_type: QbField('scheduler_type', dtype=str) -transport_type: QbField('transport_type', dtype=str) -uuid: QbField('uuid', dtype=str) +description: QbStrField('description', dtype=str, is_attribute=False) +hostname: QbStrField('hostname', dtype=str, is_attribute=False) +label: QbStrField('label', dtype=str, is_attribute=False) +metadata: QbDictField('metadata', dtype=Dict[str, Any], is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +scheduler_type: QbStrField('scheduler_type', dtype=str, is_attribute=False) +transport_type: QbStrField('transport_type', dtype=str, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_Group.yml b/tests/orm/test_fields/fields_Group.yml index 8cc298609c..810f52db40 100644 --- a/tests/orm/test_fields/fields_Group.yml +++ b/tests/orm/test_fields/fields_Group.yml @@ -1,8 +1,8 @@ -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any]) -label: QbField('label', dtype=str) -pk: QbField('pk', 'id', dtype=int) -time: QbField('time', dtype=str) -type_string: QbField('type_string', dtype=str) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False) +label: QbStrField('label', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +time: QbStrField('time', dtype=str, is_attribute=False) +type_string: QbStrField('type_string', dtype=str, is_attribute=False) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_Log.yml b/tests/orm/test_fields/fields_Log.yml index e5c8ea81f8..3e5153e0a0 100644 --- a/tests/orm/test_fields/fields_Log.yml +++ b/tests/orm/test_fields/fields_Log.yml @@ -1,8 +1,8 @@ -levelname: QbField('levelname', dtype=str) -loggername: QbField('loggername', dtype=str) -message: QbField('message', dtype=str) -metadata: QbField('metadata', dtype=typing.Dict[str, typing.Any]) -node_pk: QbField('node_pk', 'dbnode_id', dtype=int) -pk: QbField('pk', 'id', dtype=int) -time: QbField('time', dtype=datetime) -uuid: QbField('uuid', dtype=str) +levelname: QbStrField('levelname', dtype=str, is_attribute=False) +loggername: QbStrField('loggername', dtype=str, is_attribute=False) +message: QbStrField('message', dtype=str, is_attribute=False) +metadata: QbDictField('metadata', dtype=Dict[str, Any], is_attribute=False) +node_pk: QbNumericField('node_pk', dtype=int, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +time: QbNumericField('time', dtype=datetime, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_User.yml b/tests/orm/test_fields/fields_User.yml index 0030402238..2eaf3af067 100644 --- a/tests/orm/test_fields/fields_User.yml +++ b/tests/orm/test_fields/fields_User.yml @@ -1,5 +1,5 @@ -email: QbField('email', dtype=str) -first_name: QbField('first_name', dtype=str) -institution: QbField('institution', dtype=str) -last_name: QbField('last_name', dtype=str) -pk: QbField('pk', 'id', dtype=int) +email: QbStrField('email', dtype=str, is_attribute=False) +first_name: QbStrField('first_name', dtype=str, is_attribute=False) +institution: QbStrField('institution', dtype=str, is_attribute=False) +last_name: QbStrField('last_name', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.array.ArrayData.yml b/tests/orm/test_fields/fields_aiida.data.core.array.ArrayData.yml index 132bffedc0..eba6460b84 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.array.ArrayData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.array.ArrayData.yml @@ -1,11 +1,12 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.array.bands.BandsData.yml b/tests/orm/test_fields/fields_aiida.data.core.array.bands.BandsData.yml index 80e6bef74b..4be2827c92 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.array.bands.BandsData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.array.bands.BandsData.yml @@ -1,21 +1,22 @@ -array_labels: QbAttrField('array_labels', dtype=typing.Union[typing.List[str],None]) -cell: QbAttrField('cell', dtype=typing.List[typing.List[float]]) -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -label_numbers: QbAttrField('label_numbers', dtype=typing.List[int]) -labels: QbAttrField('labels', dtype=typing.List[str]) -mesh: QbAttrField('mesh', dtype=typing.List[int]) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -offset: QbAttrField('offset', dtype=typing.List[float]) -pbc1: QbAttrField('pbc1', dtype=bool) -pbc2: QbAttrField('pbc2', dtype=bool) -pbc3: QbAttrField('pbc3', dtype=bool) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -units: QbAttrField('units', dtype=str) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +array_labels: QbArrayField('array_labels', dtype=Optional[List[str]], is_attribute=True) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +cell: QbArrayField('cell', dtype=List[List[float]], is_attribute=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +label_numbers: QbArrayField('label_numbers', dtype=List[int], is_attribute=True) +labels: QbArrayField('labels', dtype=List[str], is_attribute=True) +mesh: QbArrayField('mesh', dtype=List[int], is_attribute=True) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +offset: QbArrayField('offset', dtype=List[float], is_attribute=True) +pbc1: QbField('pbc1', dtype=bool, is_attribute=True) +pbc2: QbField('pbc2', dtype=bool, is_attribute=True) +pbc3: QbField('pbc3', dtype=bool, is_attribute=True) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +units: QbStrField('units', dtype=str, is_attribute=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.array.kpoints.KpointsData.yml b/tests/orm/test_fields/fields_aiida.data.core.array.kpoints.KpointsData.yml index 499f879809..f95b7aa5e6 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.array.kpoints.KpointsData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.array.kpoints.KpointsData.yml @@ -1,19 +1,20 @@ -cell: QbAttrField('cell', dtype=typing.List[typing.List[float]]) -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -label_numbers: QbAttrField('label_numbers', dtype=typing.List[int]) -labels: QbAttrField('labels', dtype=typing.List[str]) -mesh: QbAttrField('mesh', dtype=typing.List[int]) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -offset: QbAttrField('offset', dtype=typing.List[float]) -pbc1: QbAttrField('pbc1', dtype=bool) -pbc2: QbAttrField('pbc2', dtype=bool) -pbc3: QbAttrField('pbc3', dtype=bool) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +cell: QbArrayField('cell', dtype=List[List[float]], is_attribute=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +label_numbers: QbArrayField('label_numbers', dtype=List[int], is_attribute=True) +labels: QbArrayField('labels', dtype=List[str], is_attribute=True) +mesh: QbArrayField('mesh', dtype=List[int], is_attribute=True) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +offset: QbArrayField('offset', dtype=List[float], is_attribute=True) +pbc1: QbField('pbc1', dtype=bool, is_attribute=True) +pbc2: QbField('pbc2', dtype=bool, is_attribute=True) +pbc3: QbField('pbc3', dtype=bool, is_attribute=True) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.array.projection.ProjectionData.yml b/tests/orm/test_fields/fields_aiida.data.core.array.projection.ProjectionData.yml index 132bffedc0..eba6460b84 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.array.projection.ProjectionData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.array.projection.ProjectionData.yml @@ -1,11 +1,12 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.array.trajectory.TrajectoryData.yml b/tests/orm/test_fields/fields_aiida.data.core.array.trajectory.TrajectoryData.yml index aec85a4ae4..bb5110a013 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.array.trajectory.TrajectoryData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.array.trajectory.TrajectoryData.yml @@ -1,14 +1,15 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -symbols: QbAttrField('symbols', dtype=typing.List[str]) -units_positions: QbAttrField('units_positions', 'units|positions', dtype=str) -units_times: QbAttrField('units_times', 'units|times', dtype=str) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +symbols: QbArrayField('symbols', dtype=List[str], is_attribute=True) +units_positions: QbStrField('units_positions', 'units|positions', dtype=str, is_attribute=True) +units_times: QbStrField('units_times', 'units|times', dtype=str, is_attribute=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.array.xy.XyData.yml b/tests/orm/test_fields/fields_aiida.data.core.array.xy.XyData.yml index 132bffedc0..eba6460b84 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.array.xy.XyData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.array.xy.XyData.yml @@ -1,11 +1,12 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.base.BaseType.yml b/tests/orm/test_fields/fields_aiida.data.core.base.BaseType.yml index e247a0e0f6..eba6460b84 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.base.BaseType.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.base.BaseType.yml @@ -1,12 +1,12 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) -value: QbAttrField('value') +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.bool.Bool.yml b/tests/orm/test_fields/fields_aiida.data.core.bool.Bool.yml index e247a0e0f6..dcffc342af 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.bool.Bool.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.bool.Bool.yml @@ -1,12 +1,13 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) -value: QbAttrField('value') +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) +value: QbField('value', dtype=bool, is_attribute=True) diff --git a/tests/orm/test_fields/fields_aiida.data.core.cif.CifData.yml b/tests/orm/test_fields/fields_aiida.data.core.cif.CifData.yml index a68dee1951..ac27b1639e 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.cif.CifData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.cif.CifData.yml @@ -1,14 +1,15 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -formulae: QbAttrField('formulae', dtype=typing.List[str]) -label: QbField('label', dtype=str) -md5: QbAttrField('md5', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -spacegroup_numbers: QbAttrField('spacegroup_numbers', dtype=typing.List[str]) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +formulae: QbArrayField('formulae', dtype=List[str], is_attribute=True) +label: QbStrField('label', dtype=str, is_attribute=False) +md5: QbStrField('md5', dtype=str, is_attribute=True) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +spacegroup_numbers: QbArrayField('spacegroup_numbers', dtype=List[str], is_attribute=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.code.Code.yml b/tests/orm/test_fields/fields_aiida.data.core.code.Code.yml index a91a703bc9..c9aff4804d 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.code.Code.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.code.Code.yml @@ -1,17 +1,18 @@ -append_text: QbAttrField('append_text', dtype=typing.Union[str,None]) -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -input_plugin: QbAttrField('input_plugin', dtype=typing.Union[str,None]) -is_local: QbAttrField('is_local', dtype=typing.Union[bool,None]) -label: QbField('label', dtype=str) -local_executable: QbAttrField('local_executable', dtype=typing.Union[str,None]) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -prepend_text: QbAttrField('prepend_text', dtype=typing.Union[str,None]) -remote_exec_path: QbAttrField('remote_exec_path', dtype=typing.Union[str,None]) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +append_text: QbStrField('append_text', dtype=Optional[str], is_attribute=True) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +input_plugin: QbStrField('input_plugin', dtype=Optional[str], is_attribute=True) +is_local: QbField('is_local', dtype=Optional[bool], is_attribute=True) +label: QbStrField('label', dtype=str, is_attribute=False) +local_executable: QbStrField('local_executable', dtype=Optional[str], is_attribute=True) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +prepend_text: QbStrField('prepend_text', dtype=Optional[str], is_attribute=True) +remote_exec_path: QbStrField('remote_exec_path', dtype=Optional[str], is_attribute=True) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.code.containerized.ContainerizedCode.yml b/tests/orm/test_fields/fields_aiida.data.core.code.containerized.ContainerizedCode.yml index a91a703bc9..c9aff4804d 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.code.containerized.ContainerizedCode.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.code.containerized.ContainerizedCode.yml @@ -1,17 +1,18 @@ -append_text: QbAttrField('append_text', dtype=typing.Union[str,None]) -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -input_plugin: QbAttrField('input_plugin', dtype=typing.Union[str,None]) -is_local: QbAttrField('is_local', dtype=typing.Union[bool,None]) -label: QbField('label', dtype=str) -local_executable: QbAttrField('local_executable', dtype=typing.Union[str,None]) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -prepend_text: QbAttrField('prepend_text', dtype=typing.Union[str,None]) -remote_exec_path: QbAttrField('remote_exec_path', dtype=typing.Union[str,None]) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +append_text: QbStrField('append_text', dtype=Optional[str], is_attribute=True) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +input_plugin: QbStrField('input_plugin', dtype=Optional[str], is_attribute=True) +is_local: QbField('is_local', dtype=Optional[bool], is_attribute=True) +label: QbStrField('label', dtype=str, is_attribute=False) +local_executable: QbStrField('local_executable', dtype=Optional[str], is_attribute=True) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +prepend_text: QbStrField('prepend_text', dtype=Optional[str], is_attribute=True) +remote_exec_path: QbStrField('remote_exec_path', dtype=Optional[str], is_attribute=True) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.code.installed.InstalledCode.yml b/tests/orm/test_fields/fields_aiida.data.core.code.installed.InstalledCode.yml index a91a703bc9..c9aff4804d 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.code.installed.InstalledCode.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.code.installed.InstalledCode.yml @@ -1,17 +1,18 @@ -append_text: QbAttrField('append_text', dtype=typing.Union[str,None]) -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -input_plugin: QbAttrField('input_plugin', dtype=typing.Union[str,None]) -is_local: QbAttrField('is_local', dtype=typing.Union[bool,None]) -label: QbField('label', dtype=str) -local_executable: QbAttrField('local_executable', dtype=typing.Union[str,None]) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -prepend_text: QbAttrField('prepend_text', dtype=typing.Union[str,None]) -remote_exec_path: QbAttrField('remote_exec_path', dtype=typing.Union[str,None]) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +append_text: QbStrField('append_text', dtype=Optional[str], is_attribute=True) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +input_plugin: QbStrField('input_plugin', dtype=Optional[str], is_attribute=True) +is_local: QbField('is_local', dtype=Optional[bool], is_attribute=True) +label: QbStrField('label', dtype=str, is_attribute=False) +local_executable: QbStrField('local_executable', dtype=Optional[str], is_attribute=True) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +prepend_text: QbStrField('prepend_text', dtype=Optional[str], is_attribute=True) +remote_exec_path: QbStrField('remote_exec_path', dtype=Optional[str], is_attribute=True) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.code.portable.PortableCode.yml b/tests/orm/test_fields/fields_aiida.data.core.code.portable.PortableCode.yml index a91a703bc9..c9aff4804d 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.code.portable.PortableCode.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.code.portable.PortableCode.yml @@ -1,17 +1,18 @@ -append_text: QbAttrField('append_text', dtype=typing.Union[str,None]) -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -input_plugin: QbAttrField('input_plugin', dtype=typing.Union[str,None]) -is_local: QbAttrField('is_local', dtype=typing.Union[bool,None]) -label: QbField('label', dtype=str) -local_executable: QbAttrField('local_executable', dtype=typing.Union[str,None]) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -prepend_text: QbAttrField('prepend_text', dtype=typing.Union[str,None]) -remote_exec_path: QbAttrField('remote_exec_path', dtype=typing.Union[str,None]) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +append_text: QbStrField('append_text', dtype=Optional[str], is_attribute=True) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +input_plugin: QbStrField('input_plugin', dtype=Optional[str], is_attribute=True) +is_local: QbField('is_local', dtype=Optional[bool], is_attribute=True) +label: QbStrField('label', dtype=str, is_attribute=False) +local_executable: QbStrField('local_executable', dtype=Optional[str], is_attribute=True) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +prepend_text: QbStrField('prepend_text', dtype=Optional[str], is_attribute=True) +remote_exec_path: QbStrField('remote_exec_path', dtype=Optional[str], is_attribute=True) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.dict.Dict.yml b/tests/orm/test_fields/fields_aiida.data.core.dict.Dict.yml index e5de0268b5..6a053a6989 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.dict.Dict.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.dict.Dict.yml @@ -1,12 +1,13 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -dict: QbField('dict', 'attributes', dtype=typing.Dict[str, typing.Any], subscriptable=True) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +dict: QbDictField('dict', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.enum.EnumData.yml b/tests/orm/test_fields/fields_aiida.data.core.enum.EnumData.yml index 132bffedc0..eba6460b84 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.enum.EnumData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.enum.EnumData.yml @@ -1,11 +1,12 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.float.Float.yml b/tests/orm/test_fields/fields_aiida.data.core.float.Float.yml index e247a0e0f6..5abc6a38b9 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.float.Float.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.float.Float.yml @@ -1,12 +1,13 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) -value: QbAttrField('value') +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) +value: QbNumericField('value', dtype=float, is_attribute=True) diff --git a/tests/orm/test_fields/fields_aiida.data.core.folder.FolderData.yml b/tests/orm/test_fields/fields_aiida.data.core.folder.FolderData.yml index 132bffedc0..eba6460b84 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.folder.FolderData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.folder.FolderData.yml @@ -1,11 +1,12 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.int.Int.yml b/tests/orm/test_fields/fields_aiida.data.core.int.Int.yml index e247a0e0f6..b8216dc3b7 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.int.Int.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.int.Int.yml @@ -1,12 +1,13 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) -value: QbAttrField('value') +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) +value: QbNumericField('value', dtype=int, is_attribute=True) diff --git a/tests/orm/test_fields/fields_aiida.data.core.jsonable.JsonableData.yml b/tests/orm/test_fields/fields_aiida.data.core.jsonable.JsonableData.yml index 132bffedc0..eba6460b84 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.jsonable.JsonableData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.jsonable.JsonableData.yml @@ -1,11 +1,12 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.list.List.yml b/tests/orm/test_fields/fields_aiida.data.core.list.List.yml index 132bffedc0..eba6460b84 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.list.List.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.list.List.yml @@ -1,11 +1,12 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.numeric.NumericType.yml b/tests/orm/test_fields/fields_aiida.data.core.numeric.NumericType.yml index e247a0e0f6..eba6460b84 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.numeric.NumericType.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.numeric.NumericType.yml @@ -1,12 +1,12 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) -value: QbAttrField('value') +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.orbital.OrbitalData.yml b/tests/orm/test_fields/fields_aiida.data.core.orbital.OrbitalData.yml index 132bffedc0..eba6460b84 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.orbital.OrbitalData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.orbital.OrbitalData.yml @@ -1,11 +1,12 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.remote.RemoteData.yml b/tests/orm/test_fields/fields_aiida.data.core.remote.RemoteData.yml index 401e98149a..0eece2a5c3 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.remote.RemoteData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.remote.RemoteData.yml @@ -1,12 +1,13 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -remote_path: QbAttrField('remote_path', dtype=str) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +remote_path: QbStrField('remote_path', dtype=str, is_attribute=True) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.remote.stash.RemoteStashData.yml b/tests/orm/test_fields/fields_aiida.data.core.remote.stash.RemoteStashData.yml index 6f9b4211bd..2d148dd68b 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.remote.stash.RemoteStashData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.remote.stash.RemoteStashData.yml @@ -1,12 +1,13 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -stash_mode: QbAttrField('stash_mode', dtype=str) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +stash_mode: QbStrField('stash_mode', dtype=str, is_attribute=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.remote.stash.folder.RemoteStashFolderData.yml b/tests/orm/test_fields/fields_aiida.data.core.remote.stash.folder.RemoteStashFolderData.yml index 082fcb5703..c4969fbd4d 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.remote.stash.folder.RemoteStashFolderData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.remote.stash.folder.RemoteStashFolderData.yml @@ -1,14 +1,15 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -source_list: QbAttrField('source_list', dtype=typing.List[str]) -stash_mode: QbAttrField('stash_mode', dtype=str) -target_basepath: QbAttrField('target_basepath', dtype=str) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +source_list: QbArrayField('source_list', dtype=List[str], is_attribute=True) +stash_mode: QbStrField('stash_mode', dtype=str, is_attribute=True) +target_basepath: QbStrField('target_basepath', dtype=str, is_attribute=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.singlefile.SinglefileData.yml b/tests/orm/test_fields/fields_aiida.data.core.singlefile.SinglefileData.yml index 132bffedc0..eba6460b84 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.singlefile.SinglefileData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.singlefile.SinglefileData.yml @@ -1,11 +1,12 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.str.Str.yml b/tests/orm/test_fields/fields_aiida.data.core.str.Str.yml index e247a0e0f6..b6d51f91a6 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.str.Str.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.str.Str.yml @@ -1,12 +1,13 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) -value: QbAttrField('value') +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) +value: QbStrField('value', dtype=str, is_attribute=True) diff --git a/tests/orm/test_fields/fields_aiida.data.core.structure.StructureData.yml b/tests/orm/test_fields/fields_aiida.data.core.structure.StructureData.yml index eaf7c67277..6b68e61ee1 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.structure.StructureData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.structure.StructureData.yml @@ -1,17 +1,18 @@ -cell: QbAttrField('cell', dtype=typing.List[typing.List[float]]) -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -kinds: QbAttrField('kinds', dtype=typing.Union[typing.List[dict],None]) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pbc1: QbAttrField('pbc1', dtype=bool) -pbc2: QbAttrField('pbc2', dtype=bool) -pbc3: QbAttrField('pbc3', dtype=bool) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -sites: QbAttrField('sites', dtype=typing.Union[typing.List[dict],None]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +cell: QbArrayField('cell', dtype=List[List[float]], is_attribute=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +kinds: QbArrayField('kinds', dtype=Optional[List[dict]], is_attribute=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pbc1: QbField('pbc1', dtype=bool, is_attribute=True) +pbc2: QbField('pbc2', dtype=bool, is_attribute=True) +pbc3: QbField('pbc3', dtype=bool, is_attribute=True) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +sites: QbArrayField('sites', dtype=Optional[List[dict]], is_attribute=True) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.data.core.upf.UpfData.yml b/tests/orm/test_fields/fields_aiida.data.core.upf.UpfData.yml index 132bffedc0..eba6460b84 100644 --- a/tests/orm/test_fields/fields_aiida.data.core.upf.UpfData.yml +++ b/tests/orm/test_fields/fields_aiida.data.core.upf.UpfData.yml @@ -1,11 +1,12 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.node.data.Data.yml b/tests/orm/test_fields/fields_aiida.node.data.Data.yml index 132bffedc0..eba6460b84 100644 --- a/tests/orm/test_fields/fields_aiida.node.data.Data.yml +++ b/tests/orm/test_fields/fields_aiida.node.data.Data.yml @@ -1,11 +1,12 @@ -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -pk: QbField('pk', 'id', dtype=int) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -source: QbAttrField('source', dtype=typing.Union[dict,None], subscriptable=True) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +source: QbDictField('source', dtype=Optional[dict], is_attribute=True, is_subscriptable=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.node.process.ProcessNode.yml b/tests/orm/test_fields/fields_aiida.node.process.ProcessNode.yml index 635aa8f97d..772a62237d 100644 --- a/tests/orm/test_fields/fields_aiida.node.process.ProcessNode.yml +++ b/tests/orm/test_fields/fields_aiida.node.process.ProcessNode.yml @@ -1,20 +1,21 @@ -computer_pk: QbField('computer_pk', 'dbcomputer_id', dtype=typing.Union[int,None]) -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -exception: QbAttrField('exception', dtype=typing.Union[str,None]) -exit_message: QbAttrField('exit_message', dtype=typing.Union[str,None]) -exit_status: QbAttrField('exit_status', dtype=typing.Union[int,None]) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -paused: QbAttrField('paused', dtype=bool) -pk: QbField('pk', 'id', dtype=int) -process_label: QbAttrField('process_label', dtype=typing.Union[str,None]) -process_state: QbAttrField('process_state', dtype=typing.Union[str,None]) -process_status: QbAttrField('process_status', dtype=typing.Union[str,None]) -process_type: QbField('process_type', dtype=typing.Union[str,None]) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -sealed: QbAttrField('sealed', dtype=bool) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +computer_pk: QbNumericField('computer_pk', dtype=Optional[int], is_attribute=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +exception: QbStrField('exception', dtype=Optional[str], is_attribute=True) +exit_message: QbStrField('exit_message', dtype=Optional[str], is_attribute=True) +exit_status: QbNumericField('exit_status', dtype=Optional[int], is_attribute=True) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +paused: QbField('paused', dtype=bool, is_attribute=True) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +process_label: QbStrField('process_label', dtype=Optional[str], is_attribute=True) +process_state: QbStrField('process_state', dtype=Optional[str], is_attribute=True) +process_status: QbStrField('process_status', dtype=Optional[str], is_attribute=True) +process_type: QbStrField('process_type', dtype=Optional[str], is_attribute=True) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +sealed: QbField('sealed', dtype=bool, is_attribute=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.node.process.calculation.CalculationNode.yml b/tests/orm/test_fields/fields_aiida.node.process.calculation.CalculationNode.yml index 635aa8f97d..772a62237d 100644 --- a/tests/orm/test_fields/fields_aiida.node.process.calculation.CalculationNode.yml +++ b/tests/orm/test_fields/fields_aiida.node.process.calculation.CalculationNode.yml @@ -1,20 +1,21 @@ -computer_pk: QbField('computer_pk', 'dbcomputer_id', dtype=typing.Union[int,None]) -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -exception: QbAttrField('exception', dtype=typing.Union[str,None]) -exit_message: QbAttrField('exit_message', dtype=typing.Union[str,None]) -exit_status: QbAttrField('exit_status', dtype=typing.Union[int,None]) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -paused: QbAttrField('paused', dtype=bool) -pk: QbField('pk', 'id', dtype=int) -process_label: QbAttrField('process_label', dtype=typing.Union[str,None]) -process_state: QbAttrField('process_state', dtype=typing.Union[str,None]) -process_status: QbAttrField('process_status', dtype=typing.Union[str,None]) -process_type: QbField('process_type', dtype=typing.Union[str,None]) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -sealed: QbAttrField('sealed', dtype=bool) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +computer_pk: QbNumericField('computer_pk', dtype=Optional[int], is_attribute=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +exception: QbStrField('exception', dtype=Optional[str], is_attribute=True) +exit_message: QbStrField('exit_message', dtype=Optional[str], is_attribute=True) +exit_status: QbNumericField('exit_status', dtype=Optional[int], is_attribute=True) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +paused: QbField('paused', dtype=bool, is_attribute=True) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +process_label: QbStrField('process_label', dtype=Optional[str], is_attribute=True) +process_state: QbStrField('process_state', dtype=Optional[str], is_attribute=True) +process_status: QbStrField('process_status', dtype=Optional[str], is_attribute=True) +process_type: QbStrField('process_type', dtype=Optional[str], is_attribute=True) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +sealed: QbField('sealed', dtype=bool, is_attribute=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.node.process.calculation.calcfunction.CalcFunctionNode.yml b/tests/orm/test_fields/fields_aiida.node.process.calculation.calcfunction.CalcFunctionNode.yml index 635aa8f97d..772a62237d 100644 --- a/tests/orm/test_fields/fields_aiida.node.process.calculation.calcfunction.CalcFunctionNode.yml +++ b/tests/orm/test_fields/fields_aiida.node.process.calculation.calcfunction.CalcFunctionNode.yml @@ -1,20 +1,21 @@ -computer_pk: QbField('computer_pk', 'dbcomputer_id', dtype=typing.Union[int,None]) -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -exception: QbAttrField('exception', dtype=typing.Union[str,None]) -exit_message: QbAttrField('exit_message', dtype=typing.Union[str,None]) -exit_status: QbAttrField('exit_status', dtype=typing.Union[int,None]) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -paused: QbAttrField('paused', dtype=bool) -pk: QbField('pk', 'id', dtype=int) -process_label: QbAttrField('process_label', dtype=typing.Union[str,None]) -process_state: QbAttrField('process_state', dtype=typing.Union[str,None]) -process_status: QbAttrField('process_status', dtype=typing.Union[str,None]) -process_type: QbField('process_type', dtype=typing.Union[str,None]) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -sealed: QbAttrField('sealed', dtype=bool) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +computer_pk: QbNumericField('computer_pk', dtype=Optional[int], is_attribute=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +exception: QbStrField('exception', dtype=Optional[str], is_attribute=True) +exit_message: QbStrField('exit_message', dtype=Optional[str], is_attribute=True) +exit_status: QbNumericField('exit_status', dtype=Optional[int], is_attribute=True) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +paused: QbField('paused', dtype=bool, is_attribute=True) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +process_label: QbStrField('process_label', dtype=Optional[str], is_attribute=True) +process_state: QbStrField('process_state', dtype=Optional[str], is_attribute=True) +process_status: QbStrField('process_status', dtype=Optional[str], is_attribute=True) +process_type: QbStrField('process_type', dtype=Optional[str], is_attribute=True) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +sealed: QbField('sealed', dtype=bool, is_attribute=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.node.process.calculation.calcjob.CalcJobNode.yml b/tests/orm/test_fields/fields_aiida.node.process.calculation.calcjob.CalcJobNode.yml index ec869a30fa..ec30d47fe0 100644 --- a/tests/orm/test_fields/fields_aiida.node.process.calculation.calcjob.CalcJobNode.yml +++ b/tests/orm/test_fields/fields_aiida.node.process.calculation.calcjob.CalcJobNode.yml @@ -1,30 +1,33 @@ -computer_pk: QbField('computer_pk', 'dbcomputer_id', dtype=typing.Union[int,None]) -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -detailed_job_info: QbAttrField('detailed_job_info', dtype=typing.Union[dict,None]) -exception: QbAttrField('exception', dtype=typing.Union[str,None]) -exit_message: QbAttrField('exit_message', dtype=typing.Union[str,None]) -exit_status: QbAttrField('exit_status', dtype=typing.Union[int,None]) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -imported: QbAttrField('imported', dtype=typing.Union[bool,None]) -job_id: QbAttrField('job_id', dtype=typing.Union[str,None]) -label: QbField('label', dtype=str) -last_job_info: QbAttrField('last_job_info', dtype=typing.Union[str,None]) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -paused: QbAttrField('paused', dtype=bool) -pk: QbField('pk', 'id', dtype=int) -process_label: QbAttrField('process_label', dtype=typing.Union[str,None]) -process_state: QbAttrField('process_state', dtype=typing.Union[str,None]) -process_status: QbAttrField('process_status', dtype=typing.Union[str,None]) -process_type: QbField('process_type', dtype=typing.Union[str,None]) -remote_workdir: QbAttrField('remote_workdir', dtype=typing.Union[str,None]) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -retrieve_list: QbAttrField('retrieve_list', dtype=typing.Union[typing.List[str],None]) -retrieve_temporary_list: QbAttrField('retrieve_temporary_list', dtype=typing.Union[typing.List[str],None]) -scheduler_lastchecktime: QbAttrField('scheduler_lastchecktime', dtype=typing.Union[str,None]) -scheduler_state: QbAttrField('scheduler_state', dtype=typing.Union[str,None]) -sealed: QbAttrField('sealed', dtype=bool) -state: QbAttrField('state', dtype=typing.Union[str,None]) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +computer_pk: QbNumericField('computer_pk', dtype=Optional[int], is_attribute=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +detailed_job_info: QbDictField('detailed_job_info', dtype=Optional[dict], is_attribute=True) +exception: QbStrField('exception', dtype=Optional[str], is_attribute=True) +exit_message: QbStrField('exit_message', dtype=Optional[str], is_attribute=True) +exit_status: QbNumericField('exit_status', dtype=Optional[int], is_attribute=True) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +imported: QbField('imported', dtype=Optional[bool], is_attribute=True) +job_id: QbStrField('job_id', dtype=Optional[str], is_attribute=True) +label: QbStrField('label', dtype=str, is_attribute=False) +last_job_info: QbStrField('last_job_info', dtype=Optional[str], is_attribute=True) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +paused: QbField('paused', dtype=bool, is_attribute=True) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +process_label: QbStrField('process_label', dtype=Optional[str], is_attribute=True) +process_state: QbStrField('process_state', dtype=Optional[str], is_attribute=True) +process_status: QbStrField('process_status', dtype=Optional[str], is_attribute=True) +process_type: QbStrField('process_type', dtype=Optional[str], is_attribute=True) +remote_workdir: QbStrField('remote_workdir', dtype=Optional[str], is_attribute=True) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +retrieve_list: QbArrayField('retrieve_list', dtype=Optional[List[str]], is_attribute=True) +retrieve_temporary_list: QbArrayField('retrieve_temporary_list', dtype=Optional[List[str]], + is_attribute=True) +scheduler_lastchecktime: QbStrField('scheduler_lastchecktime', dtype=Optional[str], + is_attribute=True) +scheduler_state: QbStrField('scheduler_state', dtype=Optional[str], is_attribute=True) +sealed: QbField('sealed', dtype=bool, is_attribute=True) +state: QbStrField('state', dtype=Optional[str], is_attribute=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.node.process.workflow.WorkflowNode.yml b/tests/orm/test_fields/fields_aiida.node.process.workflow.WorkflowNode.yml index 635aa8f97d..772a62237d 100644 --- a/tests/orm/test_fields/fields_aiida.node.process.workflow.WorkflowNode.yml +++ b/tests/orm/test_fields/fields_aiida.node.process.workflow.WorkflowNode.yml @@ -1,20 +1,21 @@ -computer_pk: QbField('computer_pk', 'dbcomputer_id', dtype=typing.Union[int,None]) -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -exception: QbAttrField('exception', dtype=typing.Union[str,None]) -exit_message: QbAttrField('exit_message', dtype=typing.Union[str,None]) -exit_status: QbAttrField('exit_status', dtype=typing.Union[int,None]) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -paused: QbAttrField('paused', dtype=bool) -pk: QbField('pk', 'id', dtype=int) -process_label: QbAttrField('process_label', dtype=typing.Union[str,None]) -process_state: QbAttrField('process_state', dtype=typing.Union[str,None]) -process_status: QbAttrField('process_status', dtype=typing.Union[str,None]) -process_type: QbField('process_type', dtype=typing.Union[str,None]) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -sealed: QbAttrField('sealed', dtype=bool) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +computer_pk: QbNumericField('computer_pk', dtype=Optional[int], is_attribute=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +exception: QbStrField('exception', dtype=Optional[str], is_attribute=True) +exit_message: QbStrField('exit_message', dtype=Optional[str], is_attribute=True) +exit_status: QbNumericField('exit_status', dtype=Optional[int], is_attribute=True) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +paused: QbField('paused', dtype=bool, is_attribute=True) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +process_label: QbStrField('process_label', dtype=Optional[str], is_attribute=True) +process_state: QbStrField('process_state', dtype=Optional[str], is_attribute=True) +process_status: QbStrField('process_status', dtype=Optional[str], is_attribute=True) +process_type: QbStrField('process_type', dtype=Optional[str], is_attribute=True) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +sealed: QbField('sealed', dtype=bool, is_attribute=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.node.process.workflow.workchain.WorkChainNode.yml b/tests/orm/test_fields/fields_aiida.node.process.workflow.workchain.WorkChainNode.yml index 635aa8f97d..772a62237d 100644 --- a/tests/orm/test_fields/fields_aiida.node.process.workflow.workchain.WorkChainNode.yml +++ b/tests/orm/test_fields/fields_aiida.node.process.workflow.workchain.WorkChainNode.yml @@ -1,20 +1,21 @@ -computer_pk: QbField('computer_pk', 'dbcomputer_id', dtype=typing.Union[int,None]) -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -exception: QbAttrField('exception', dtype=typing.Union[str,None]) -exit_message: QbAttrField('exit_message', dtype=typing.Union[str,None]) -exit_status: QbAttrField('exit_status', dtype=typing.Union[int,None]) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -paused: QbAttrField('paused', dtype=bool) -pk: QbField('pk', 'id', dtype=int) -process_label: QbAttrField('process_label', dtype=typing.Union[str,None]) -process_state: QbAttrField('process_state', dtype=typing.Union[str,None]) -process_status: QbAttrField('process_status', dtype=typing.Union[str,None]) -process_type: QbField('process_type', dtype=typing.Union[str,None]) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -sealed: QbAttrField('sealed', dtype=bool) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +computer_pk: QbNumericField('computer_pk', dtype=Optional[int], is_attribute=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +exception: QbStrField('exception', dtype=Optional[str], is_attribute=True) +exit_message: QbStrField('exit_message', dtype=Optional[str], is_attribute=True) +exit_status: QbNumericField('exit_status', dtype=Optional[int], is_attribute=True) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +paused: QbField('paused', dtype=bool, is_attribute=True) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +process_label: QbStrField('process_label', dtype=Optional[str], is_attribute=True) +process_state: QbStrField('process_state', dtype=Optional[str], is_attribute=True) +process_status: QbStrField('process_status', dtype=Optional[str], is_attribute=True) +process_type: QbStrField('process_type', dtype=Optional[str], is_attribute=True) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +sealed: QbField('sealed', dtype=bool, is_attribute=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False) diff --git a/tests/orm/test_fields/fields_aiida.node.process.workflow.workfunction.WorkFunctionNode.yml b/tests/orm/test_fields/fields_aiida.node.process.workflow.workfunction.WorkFunctionNode.yml index 635aa8f97d..772a62237d 100644 --- a/tests/orm/test_fields/fields_aiida.node.process.workflow.workfunction.WorkFunctionNode.yml +++ b/tests/orm/test_fields/fields_aiida.node.process.workflow.workfunction.WorkFunctionNode.yml @@ -1,20 +1,21 @@ -computer_pk: QbField('computer_pk', 'dbcomputer_id', dtype=typing.Union[int,None]) -ctime: QbField('ctime', dtype=datetime) -description: QbField('description', dtype=str) -exception: QbAttrField('exception', dtype=typing.Union[str,None]) -exit_message: QbAttrField('exit_message', dtype=typing.Union[str,None]) -exit_status: QbAttrField('exit_status', dtype=typing.Union[int,None]) -extras: QbField('extras', dtype=typing.Dict[str, typing.Any], subscriptable=True) -label: QbField('label', dtype=str) -mtime: QbField('mtime', dtype=datetime) -node_type: QbField('node_type', dtype=str) -paused: QbAttrField('paused', dtype=bool) -pk: QbField('pk', 'id', dtype=int) -process_label: QbAttrField('process_label', dtype=typing.Union[str,None]) -process_state: QbAttrField('process_state', dtype=typing.Union[str,None]) -process_status: QbAttrField('process_status', dtype=typing.Union[str,None]) -process_type: QbField('process_type', dtype=typing.Union[str,None]) -repository_metadata: QbField('repository_metadata', dtype=typing.Dict[str, typing.Any]) -sealed: QbAttrField('sealed', dtype=bool) -user_pk: QbField('user_pk', 'user_id', dtype=int) -uuid: QbField('uuid', dtype=str) +attributes: QbDictField('attributes', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +computer_pk: QbNumericField('computer_pk', dtype=Optional[int], is_attribute=True) +ctime: QbNumericField('ctime', dtype=datetime, is_attribute=False) +description: QbStrField('description', dtype=str, is_attribute=False) +exception: QbStrField('exception', dtype=Optional[str], is_attribute=True) +exit_message: QbStrField('exit_message', dtype=Optional[str], is_attribute=True) +exit_status: QbNumericField('exit_status', dtype=Optional[int], is_attribute=True) +extras: QbDictField('extras', dtype=Dict[str, Any], is_attribute=False, is_subscriptable=True) +label: QbStrField('label', dtype=str, is_attribute=False) +mtime: QbNumericField('mtime', dtype=datetime, is_attribute=False) +node_type: QbStrField('node_type', dtype=str, is_attribute=False) +paused: QbField('paused', dtype=bool, is_attribute=True) +pk: QbNumericField('pk', dtype=int, is_attribute=False) +process_label: QbStrField('process_label', dtype=Optional[str], is_attribute=True) +process_state: QbStrField('process_state', dtype=Optional[str], is_attribute=True) +process_status: QbStrField('process_status', dtype=Optional[str], is_attribute=True) +process_type: QbStrField('process_type', dtype=Optional[str], is_attribute=True) +repository_metadata: QbDictField('repository_metadata', dtype=Dict[str, Any], is_attribute=False) +sealed: QbField('sealed', dtype=bool, is_attribute=True) +user_pk: QbNumericField('user_pk', dtype=int, is_attribute=False) +uuid: QbStrField('uuid', dtype=str, is_attribute=False)