def on_deserialize(self, value): value = callable_to_dict(value) for key in value: item = value[key] if item is not None and not checkers.is_callable(item): raise SQLAthanorError('on_deserialize for %s must be callable' % key) self._on_deserialize = value
def __init__(self, argument, supports_json=False, supports_yaml=False, supports_dict=False, on_serialize=None, on_deserialize=None, **kwargs): """Provide a relationship between two mapped classes. This corresponds to a parent-child or associate table relationship. The constructed class is an instance of :class:`RelationshipProperty`. When serializing or de-serializing relationships, they essentially become "nested" objects. For example, if you have an ``Account`` table with a relationship to a ``User`` table, you might want to nest or embed a list of ``User`` objects within a serialized ``Account`` object. .. caution:: Unlike columns, properties, or hybrid properties, relationships cannot be serialized to CSV. This is because a serialized relationship is essentially a "nested" object within another object. Therefore, the ``supports_csv`` option cannot be set and will always be interpreted as ``False``. .. warning:: This constructor is analogous to the original :ref:`SQLAlchemy relationship() <sqlalchemy:sqlalchemy.orm.relationship>` from which it inherits. The only difference is that it supports additional keyword arguments which are not supported in the original, and which are documented below. **For the original SQLAlchemy version, see:** :ref:`(SQLAlchemy) relationship() <sqlalchemy:sqlalchemy.orm.relationship>` :param argument: see :ref:`(SQLAlchemy) relationship() <sqlalchemy:sqlalchemy.orm.relationship>` :param supports_json: Determines whether the column can be serialized to or de-serialized from JSON format. If ``True``, can be serialized to JSON and de-serialized from JSON. If ``False``, will not be included when serialized to JSON and will be ignored if present in a de-serialized JSON. Can also accept a 2-member :class:`tuple <python:tuple>` (inbound / outbound) which determines de-serialization and serialization support respectively. Defaults to ``False``, which means the column will not be serialized to JSON or de-serialized from JSON. :type supports_json: :class:`bool <python:bool>` / :class:`tuple <python:tuple>` of form (inbound: :class:`bool <python:bool>`, outbound: :class:`bool <python:bool>`) :param supports_yaml: Determines whether the column can be serialized to or de-serialized from YAML format. If ``True``, can be serialized to YAML and de-serialized from YAML. If ``False``, will not be included when serialized to YAML and will be ignored if present in a de-serialized YAML. Can also accept a 2-member :class:`tuple <python:tuple>` (inbound / outbound) which determines de-serialization and serialization support respectively. Defaults to ``False``, which means the column will not be serialized to YAML or de-serialized from YAML. :type supports_yaml: :class:`bool <python:bool>` / :class:`tuple <python:tuple>` of form (inbound: :class:`bool <python:bool>`, outbound: :class:`bool <python:bool>`) :param supports_dict: Determines whether the column can be serialized to or de-serialized to a Python :class:`dict <python:dict>`. If ``True``, can be serialized to :class:`dict <python:dict>` and de-serialized from a :class:`dict <python:dict>`. If ``False``, will not be included when serialized to :class:`dict <python:dict>` and will be ignored if present in a de-serialized :class:`dict <python:dict>`. Can also accept a 2-member :class:`tuple <python:tuple>` (inbound / outbound) which determines de-serialization and serialization support respectively. Defaults to ``False``, which means the column will not be serialized to a :class:`dict <python:dict>` or de-serialized from a :class:`dict <python:dict>`. :type supports_dict: :class:`bool <python:bool>` / :class:`tuple <python:tuple>` of form (inbound: :class:`bool <python:bool>`, outbound: :class:`bool <python:bool>`) """ # pylint: disable=too-many-branches if on_serialize is not None and not isinstance(on_serialize, dict): on_serialize = { 'csv': on_serialize, 'json': on_serialize, 'yaml': on_serialize, 'dict': on_serialize } elif on_serialize is not None: if 'csv' not in on_serialize: on_serialize['csv'] = None if 'json' not in on_serialize: on_serialize['json'] = None if 'yaml' not in on_serialize: on_serialize['yaml'] = None if 'dict' not in on_serialize: on_serialize['dict'] = None else: on_serialize = { 'csv': None, 'json': None, 'yaml': None, 'dict': None } for key in on_serialize: item = on_serialize[key] if item is not None and not checkers.is_callable(item): raise SQLAthanorError('on_serialize for %s must be callable' % key) if on_deserialize is not None and not isinstance(on_deserialize, dict): on_deserialize = { 'csv': on_deserialize, 'json': on_deserialize, 'yaml': on_deserialize, 'dict': on_deserialize } elif on_deserialize is not None: if 'csv' not in on_deserialize: on_deserialize['csv'] = None if 'json' not in on_deserialize: on_deserialize['json'] = None if 'yaml' not in on_deserialize: on_deserialize['yaml'] = None if 'dict' not in on_deserialize: on_deserialize['dict'] = None else: on_deserialize = { 'csv': None, 'json': None, 'yaml': None, 'dict': None } for key in on_deserialize: item = on_deserialize[key] if item is not None and not checkers.is_callable(item): raise SQLAthanorError( 'on_deserialize for %s must be callable' % key) if supports_json is True: supports_json = (True, True) elif not supports_json: supports_json = (False, False) if supports_yaml is True: supports_yaml = (True, True) elif not supports_yaml: supports_yaml = (False, False) if supports_dict is True: supports_dict = (True, True) elif not supports_dict: supports_dict = (False, False) self.supports_csv = (False, False) self.csv_sequence = None self.supports_json = supports_json self.supports_yaml = supports_yaml self.supports_dict = supports_dict self.on_serialize = on_serialize self.on_deserialize = on_deserialize comparator_factory = kwargs.pop('comparator_factory', RelationshipProperty.Comparator) super(RelationshipProperty, self).__init__(argument, comparator_factory=comparator_factory, **kwargs)