Dictalchemy

Dictalchemy adds utils.asdict() and utils.fromdict() methods to SQLAlchemy declarative models.

Currently this works with synonyms and simple relationships as one-to-many and many-to-many. Relationships can be followed in many levels.

Using DictableModel

classes.DictableModel can be used as base class for declarative_base or as a mixin for a declarative class.

Example usage:

from dictalchemy import DictableModel
from slqlachemy.ext.declarative import declarative_base
Base = declarative_base(cls=DictableModel)

Using make_class_dictable()

This method can be run on existing classes to make them dictable.

Example:

Base = declarative_base()
make_class_dictable(Base)

Default values

Default values are defined in dictalchemy.constants.

Using asdict()

Any collection that inherits from dict or list is supported together with sqlalchemy.orm.dynamic.AppenderMixin, sqlalchemy.orm.query.Query sqlalchemy.orm.associationproxy._AssociationList and sqlalchemy.orm.associationproxy._AssociationDict.

Simple example:

>>> session.query(User).asdict()
{'id': 1, 'username': 'Gerald'}

Using exclude_pk:

>>> session.query(User).asdict(exclude_pk=True)
{'username': 'Gerald'}

Using exclude:

>>> session.query(User).asdict(exclude=['id'])
{'username': 'Gerald'}

Using follow without arguments:

>>> session.query(User).asdict(follow={'groups':{}})
{'username': 'Gerald', groups=[{'id': 1, 'name': 'User'}]}

Using follow with arguments:

>>> session.query(User).asdict(follow={'groups':{'exclude': ['id']})
{'username': 'Gerald', groups=[{'name': 'User'}]}

Using follow with a parent argument:

>>> session.query(User).asdict(follow={'groups':{'parent': 'relationships', 'exclude': ['id']})
{'username': 'Gerald', 'relationships': {'groups':[{'name': 'User'}]}}

Using include(for example for including synonyms/properties):

>>> session.query(User).asdict(include=['displayname']
{'id': 1, 'username': 'Gerald', 'displayname': 'Gerald'}

The asdict argument method

Note

New in v 0.1.2.1

The argument method is used to determine which method asdict should call when following relations. If method is set in the follow arguments that method will be used instead. See the HAL example in dictalchemy.utils.asdict().

Using fromdict()

Without arguments:

>>> user = session.query(User).first()
>>> dict(user)
{'id': 3, 'name': 'Gerald'}
>>> user.fromdict({'name': 'Gerald the Great'})
>>> dict(user)
{'name': 'Gerald the Great'}

Excluding underscore:

>>> user = session.query(User).first()
>>> dict(user, only=["_secret_id"])
{'_secret_id': 1}
>>> user.fromdict({'_secret_id': 2}, exclude_underscore=False)
>>> dict(user, only=["_secret_id"])
{'_secret_id': 2}

Updating primary key:

>>> user = session.query(User).first()
>>> dict(user, only=["id"])
{'id': 3}
>>> user.fromdict({'id': 2}, allow_pk=True)
>>> dict(user, only=["id"])
{'id': 2}

Updating relationships:

>>> dict(user, follow=['address'])
{'name': 'Gerald the Great', 'address': {'street': None}}
>>> user.fromdict({'address': {'street': 'Main street'})
>>> dict(user, follow=['address'])
{'name': 'Gerald the Great', 'address': {'street': 'Main street'}}

Using include:

>>> user = session.query(User).first()
>>> dict(user)
{'id': 3, 'name': 'Gerald', 'a_synonym': 'Data'}
>>> user.fromdict({'name': 'Gerald the Great', 'a_synonym': 'Other data'}, include=['a_synonym'])
>>> dict(user)
{'name': 'Gerald the Great', 'a_synonym': 'Other data'}

Using only:

>>> user = session.query(User).first()
>>> dict(user)
{'id': 3, 'name': 'Gerald', 'a_synonym': 'Data'}
>>> user.fromdict({'name': 'Gerald the Great', 'a_synonym': 'Other data'}, only=['name'])
>>> dict(user)
{'name': 'Gerald the Great', 'a_synonym': 'Data'}

API

Classes

Contains DictableModel that can be used as a base class for sqlalchemy.ext.declarative_base().

class dictalchemy.classes.DictableModel[source]

Bases: object

Can be used as a base class for sqlalchemy.ext.declarative()

Contains the methods DictableModel.__iter__(), DictableModel.asdict() and DictableModel.fromdict().

Variables:
  • dictalchemy_exclude – List of properties that should always be excluded.
  • dictalchemy_exclude_underscore – If True properties starting with an underscore will always be excluded.
  • dictalchemy_fromdict_allow_pk – If True the primary key can be updated by DictableModel.fromdict().
  • dictalchemy_asdict_include – List of properties that should always be included when calling DictableModel.asdict()
  • dictalchemy_fromdict_include – List of properties that should always be included when calling DictableModel.fromdict()
__iter__(model)

iter method for models

Yields everything returned by asdict.

__weakref__

list of weak references to the object (if defined)

asdict(model, exclude=None, exclude_underscore=None, exclude_pk=None, follow=None, include=None, only=None, method='asdict', **kwargs)

Get a dict from a model

Using the method parameter makes it possible to have multiple methods that formats the result.

Additional keyword arguments will be passed to all relationships that are followed. This can be used to pass on things like request or context.

Parameters:
  • follow – List or dict of relationships that should be followed. If the parameter is a dict the value should be a dict of keyword arguments. Currently it follows InstrumentedList, MappedCollection and regular 1:1, 1:m, m:m relationships. Follow takes an extra argument, ‘method’, which is the method that should be used on the relation. It also takes the extra argument ‘parent’ which determines where the relationships data should be added in the response dict. If ‘parent’ is set the relationship will be added with it’s own key as a child to parent.
  • exclude – List of properties that should be excluded, will be merged with model.dictalchemy_exclude
  • exclude_pk – If True any column that refers to the primary key will be excluded.
  • exclude_underscore – Overides model.dictalchemy_exclude_underscore if set
  • include – List of properties that should be included. Use this to allow python properties to be called. This list will be merged with model.dictalchemy_asdict_include or model.dictalchemy_include.
  • only – List of properties that should be included. This will override everything else except follow.
  • method – Name of the method that is currently called. This will be the default method used in ‘follow’ unless another method is set.
Raises:

dictalchemy.errors.MissingRelationError if follow contains a non-existent relationship.

Raises:

dictalchemy.errors.UnsupportedRelationError If follow contains an existing relationship that currently isn’t supported.

Returns:

dict

fromdict(model, data, exclude=None, exclude_underscore=None, allow_pk=None, follow=None, include=None, only=None)

Update a model from a dict

Works almost identically as dictalchemy.utils.asdict(). However, it will not create missing instances or update collections.

This method updates the following properties on a model:

  • Simple columns
  • Synonyms
  • Simple 1-m relationships
Parameters:
  • data – dict of data
  • exclude – list of properties that should be excluded
  • exclude_underscore – If True underscore properties will be excluded, if set to None model.dictalchemy_exclude_underscore will be used.
  • allow_pk – If True any column that refers to the primary key will be excluded. Defaults model.dictalchemy_fromdict_allow_pk or dictable.constants.fromdict_allow_pk. If set to True a primary key can still be excluded with the exclude parameter.
  • follow – Dict of relations that should be followed, the key is the arguments passed to the relation. Relations only works on simple relations, not on lists.
  • include – List of properties that should be included. This list will override anything in the exclude list. It will not override allow_pk.
  • only – List of the only properties that should be returned. This will not override allow_pk or follow.
Raises:

dictalchemy.errors.DictalchemyError If a primary key is in data and allow_pk is False

Returns:

The model

Utilities

dictalchemy.utils.arg_to_dict(arg)[source]

Convert an argument that can be None, list/tuple or dict to dict

Example:

>>> arg_to_dict(None)
[]
>>> arg_to_dict(['a', 'b'])
{'a':{},'b':{}}
>>> arg_to_dict({'a':{'only': 'id'}, 'b':{'only': 'id'}})
{'a':{'only':'id'},'b':{'only':'id'}}
Returns:dict with keys and dict arguments as value
dictalchemy.utils.asdict(model, exclude=None, exclude_underscore=None, exclude_pk=None, follow=None, include=None, only=None, method='asdict', **kwargs)[source]

Get a dict from a model

Using the method parameter makes it possible to have multiple methods that formats the result.

Additional keyword arguments will be passed to all relationships that are followed. This can be used to pass on things like request or context.

Parameters:
  • follow – List or dict of relationships that should be followed. If the parameter is a dict the value should be a dict of keyword arguments. Currently it follows InstrumentedList, MappedCollection and regular 1:1, 1:m, m:m relationships. Follow takes an extra argument, ‘method’, which is the method that should be used on the relation. It also takes the extra argument ‘parent’ which determines where the relationships data should be added in the response dict. If ‘parent’ is set the relationship will be added with it’s own key as a child to parent.
  • exclude – List of properties that should be excluded, will be merged with model.dictalchemy_exclude
  • exclude_pk – If True any column that refers to the primary key will be excluded.
  • exclude_underscore – Overides model.dictalchemy_exclude_underscore if set
  • include – List of properties that should be included. Use this to allow python properties to be called. This list will be merged with model.dictalchemy_asdict_include or model.dictalchemy_include.
  • only – List of properties that should be included. This will override everything else except follow.
  • method – Name of the method that is currently called. This will be the default method used in ‘follow’ unless another method is set.
Raises:

dictalchemy.errors.MissingRelationError if follow contains a non-existent relationship.

Raises:

dictalchemy.errors.UnsupportedRelationError If follow contains an existing relationship that currently isn’t supported.

Returns:

dict

dictalchemy.utils.fromdict(model, data, exclude=None, exclude_underscore=None, allow_pk=None, follow=None, include=None, only=None)[source]

Update a model from a dict

Works almost identically as dictalchemy.utils.asdict(). However, it will not create missing instances or update collections.

This method updates the following properties on a model:

  • Simple columns
  • Synonyms
  • Simple 1-m relationships
Parameters:
  • data – dict of data
  • exclude – list of properties that should be excluded
  • exclude_underscore – If True underscore properties will be excluded, if set to None model.dictalchemy_exclude_underscore will be used.
  • allow_pk – If True any column that refers to the primary key will be excluded. Defaults model.dictalchemy_fromdict_allow_pk or dictable.constants.fromdict_allow_pk. If set to True a primary key can still be excluded with the exclude parameter.
  • follow – Dict of relations that should be followed, the key is the arguments passed to the relation. Relations only works on simple relations, not on lists.
  • include – List of properties that should be included. This list will override anything in the exclude list. It will not override allow_pk.
  • only – List of the only properties that should be returned. This will not override allow_pk or follow.
Raises:

dictalchemy.errors.DictalchemyError If a primary key is in data and allow_pk is False

Returns:

The model

dictalchemy.utils.iter(model)[source]

iter method for models

Yields everything returned by asdict.

dictalchemy.utils.make_class_dictable(cls, exclude=None, exclude_underscore=True, fromdict_allow_pk=False, include=None, asdict_include=None, fromdict_include=None)[source]

Make a class dictable

Useful for when the Base class is already defined, for example when using Flask-SQLAlchemy.

Warning: This method will overwrite existing attributes if they exists.

Parameters:
  • exclude – Will be set as dictalchemy_exclude on the class
  • exclude_underscore – Will be set as dictalchemy_exclude_underscore on the class
  • fromdict_allow_pk – Will be set as dictalchemy_fromdict_allow_pk on the class
  • include – Will be set as dictalchemy_include on the class.
  • asdict_include – Will be set as dictalchemy_asdict_include on the class. If not None it will override dictalchemy_include.
  • fromdict_include – Will be set as dictalchemy_fromdict_include on the class. If not None it will override dictalchemy_include.
Returns:

The class

Errors

exception dictalchemy.errors.DictalchemyError[source]

Bases: exceptions.Exception

Base class for Dictalchemy errors

exception dictalchemy.errors.MissingRelationError(relation_key)[source]

Bases: dictalchemy.errors.DictalchemyError

Raised when a relationship is missing

Variables:relation_key – Relation name
exception dictalchemy.errors.UnsupportedRelationError(relation_key)[source]

Bases: dictalchemy.errors.DictalchemyError

Raised when a relation is not supported by asdict or fromdict.

Variables:relation_key – Relation name

Constants

dictalchemy.constants.default_exclude = None

Default value for asdict_exclude

dictalchemy.constants.default_exclude_underscore = True

Default value for exclude_underscore if not set

dictalchemy.constants.default_fromdict_allow_pk = False

Default value for fromdict_allow_pk if not set

Python versions

Dictalchemy supports python 2.7.3 and python 3.3 through 2to3. Other versions are not tested.

Source

The source is hosted on http://github.com/danielholmstrom/dictalchemy.

License

dictalchemy is released under the MIT license.