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)
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
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 set. 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 set. 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.
License
dictalchemy is released under the MIT license.