======================================================================
Serialchemy
======================================================================
.. image:: https://img.shields.io/pypi/v/serialchemy.svg
:target: https://pypi.python.org/pypi/serialchemy
.. image:: https://img.shields.io/pypi/pyversions/serialchemy.svg
:target: https://pypi.org/project/serialchemy
.. image:: https://github.com/ESSS/serialchemy/workflows/build/badge.svg
:target: https://github.com/ESSS/serialchemy/actions
.. image:: https://codecov.io/gh/ESSS/serialchemy/branch/master/graph/badge.svg
:target: https://codecov.io/gh/ESSS/serialchemy
.. image:: https://img.shields.io/readthedocs/serialchemy.svg
:target: https://serialchemy.readthedocs.io/en/latest/
.. image:: https://sonarcloud.io/api/project_badges/measure?project=ESSS_serialchemy&metric=alert_status
:target: https://sonarcloud.io/project/overview?id=ESSS_serialchemy
SQLAlchemy model serialization.
===============================
Motivation
----------
**Serialchemy** was developed as a module of Flask-RESTAlchemy_, a lib to create Restful APIs
using Flask and SQLAlchemy. We first tried marshmallow-sqlalchemy_, probably the most
well-known lib for SQLAlchemy model serialization, but we faced `issues related to nested
models <https://github.com/marshmallow-code/marshmallow-sqlalchemy/issues/67>`_. We also think
that is possible to build a simpler and more maintainable solution by having SQLAlchemy_ in
mind from the ground up, as opposed to marshmallow-sqlalchemy_ that had to be
designed and built on top of marshmallow_.
.. _SQLAlchemy: www.sqlalchemy.org
.. _marshmallow-sqlalchemy: http://marshmallow-sqlalchemy.readthedocs.io
.. _marshmallow: https://marshmallow.readthedocs.io
.. _Flask-RESTAlchemy: https://github.com/ESSS/flask-restalchemy
How to Use it
-------------
Serializing Generic Types
.........................
Suppose we have an `Employee` SQLAlchemy_ model declared:
.. code-block:: python
class Employee(Base):
__tablename__ = "Employee"
id = Column(Integer, primary_key=True)
fullname = Column(String)
admission = Column(DateTime, default=datetime(2000, 1, 1))
company_id = Column(ForeignKey("Company.id"))
company = relationship(Company)
company_name = column_property(
select([Company.name]).where(Company.id == company_id)
)
password = Column(String)
`Generic Types`_ are automatically serialized by `ModelSerializer`:
.. code-block:: python
from serialchemy import ModelSerializer
emp = Employee(fullname="Roberto Silva", admission=datetime(2019, 4, 2))
serializer = ModelSerializer(Employee)
serializer.dump(emp)
# >>
{
"id": None,
"fullname": "Roberto Silva",
"admission": "2019-04-02T00:00:00",
"company_id": None,
"company_name": None,
"password": None,
}
New items can be deserialized by the same serializer:
.. code-block:: python
new_employee = {"fullname": "Jobson Gomes", "admission": "2018-02-03"}
serializer.load(new_employee)
# >> <Employee object at 0x000001C119DE3940>
Serializers do not commit into the database. You must do this by yourself:
.. code-block:: python
emp = serializer.load(new_employee)
session.add(emp)
session.commit()
.. _`Generic Types`: https://docs.sqlalchemy.org/en/rel_1_2/core/type_basics.html#generic-types
Custom Serializers
..................
For anything beyond `Generic Types`_ we must extend the `ModelSerializer` class:
.. code-block:: python
class EmployeeSerializer(ModelSerializer):
password = Field(load_only=True) # passwords should be only deserialized
company = NestedModelField(Company) # dump company as nested object
serializer = EmployeeSerializer(Employee)
serializer.dump(emp)
# >>
{
"id": 1,
"fullname": "Roberto Silva",
"admission": "2019-04-02T00:00:00",
"company": {"id": 3, "name": "Acme Co"},
}
Extend Polymorphic Serializer
+++++++++++++++++++++++++++++
One of the possibilities is to serialize SQLalchemy joined table inheritance and
it child tables as well. To do such it's necessary to set a variable with
the desired model class name. Take this `Employee` class with for instance and let us
assume it have a joined table inheritance:
.. code-block:: python
class Employee(Base):
...
type = Column(String(50))
__mapper_args__ = {"polymorphic_identity": "employee", "polymorphic_on": type}
class Engineer(Employee):
__tablename__ = "Engineer"
id = Column(Integer, ForeignKey("employee.id"), primary_key=True)
association = relationship(Association)
__mapper_args__ = {
"polymorphic_identity": "engineer",
}
To use a extended `ModelSerializer` class on the `Engineer` class, you should create
the serializer as it follows:
.. code-block:: python
class EmployeeSerializer(
PolymorphicModelSerializer
): # Since this class will be polymorphic
password = Field(load_only=True)
company = NestedModelField(Company)
class EngineerSerializer(EmployeeSerializer):
__model_class__ = Engineer # This is the table Serialchemy will refer to
association = NestedModelField(Association)
Contributing
------------
For guidance on setting up a development environment and how to make a
contribution to serialchemy, see the `contributing guidelines`_.
.. _contributing guidelines: https://github.com/ESSS/serialchemy/blob/master/CONTRIBUTING.rst
Release
-------
A reminder for the maintainers on how to make a new release.
Note that the VERSION should folow the semantic versioning as X.Y.Z
Ex.: v1.0.5
1. Create a ``release-VERSION`` branch from ``upstream/master``.
2. Update ``CHANGELOG.rst``.
3. Push a branch with the changes.
4. Once all builds pass, push a ``VERSION`` tag to ``upstream``.
5. Merge the PR.
History
=======
0.4.0 (2013-12-11)
------------------
* Fix to get model attribute name instead of table column name on polymorphic serializer
* Extends the PolymorphicModelSerializer to accept also column descriptors when searching
for the polymorphic column key.
* Add support for serialization of Python Enums
* Change PolymorphicModelSerializer to support inherited models of inherited models
* Change Field to use a default serializer for not None values
* Added support for sqlalchemy 1.4
* Add EnumKeySerializer
History
=======
0.4.0 (2013-12-11)
------------------
* Fix to get model attribute name instead of table column name on polymorphic serializer
* Extends the PolymorphicModelSerializer to accept also column descriptors when searching
for the polymorphic column key.
* Add support for serialization of Python Enums
* Change PolymorphicModelSerializer to support inherited models of inherited models
* Change Field to use a default serializer for not None values
* Added support for sqlalchemy 1.4
* Add EnumKeySerializer
0.3.0 (2019-17-07)
------------------
* Add the composite fields to list of properties of model, to serialize that fields if it type is in EXTRA_SERIALIZERS.
* Fix error for SQLAlchemy composite attributes
* Added free functions dump and load so users can quickly dump a SQLAlchemy model without having to instancialize
ModelSerializer.
0.2.0 (2019-03-22)
------------------
* Fix: Error when deserializing of nested models when SQLAlchemy model primary
key attribute name differs from the column name
* Allow EXTRA_SERIALIZERS to be defined in runtime
* Check if a session was given when serializing/deserializing nested fields
0.1.0 (2019-02-12)
------------------
* First release on PyPI.
Raw data
{
"_id": null,
"home_page": "https://github.com/ESSS/serialchemy",
"name": "serialchemy",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": "",
"keywords": "serialchemy",
"author": "ESSS",
"author_email": "foss@esss.co",
"download_url": "https://files.pythonhosted.org/packages/04/73/6cae80eef269aeca098de9443c401c9515fc0fd48d7ff590e987270aa720/serialchemy-0.4.0.tar.gz",
"platform": null,
"description": "======================================================================\nSerialchemy\n======================================================================\n\n\n.. image:: https://img.shields.io/pypi/v/serialchemy.svg\n :target: https://pypi.python.org/pypi/serialchemy\n\n.. image:: https://img.shields.io/pypi/pyversions/serialchemy.svg\n :target: https://pypi.org/project/serialchemy\n\n.. image:: https://github.com/ESSS/serialchemy/workflows/build/badge.svg\n :target: https://github.com/ESSS/serialchemy/actions\n\n.. image:: https://codecov.io/gh/ESSS/serialchemy/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/ESSS/serialchemy\n\n.. image:: https://img.shields.io/readthedocs/serialchemy.svg\n :target: https://serialchemy.readthedocs.io/en/latest/\n\n.. image:: https://sonarcloud.io/api/project_badges/measure?project=ESSS_serialchemy&metric=alert_status\n :target: https://sonarcloud.io/project/overview?id=ESSS_serialchemy\n\n\nSQLAlchemy model serialization.\n===============================\n\nMotivation\n----------\n\n**Serialchemy** was developed as a module of Flask-RESTAlchemy_, a lib to create Restful APIs\nusing Flask and SQLAlchemy. We first tried marshmallow-sqlalchemy_, probably the most\nwell-known lib for SQLAlchemy model serialization, but we faced `issues related to nested\nmodels <https://github.com/marshmallow-code/marshmallow-sqlalchemy/issues/67>`_. We also think\nthat is possible to build a simpler and more maintainable solution by having SQLAlchemy_ in\nmind from the ground up, as opposed to marshmallow-sqlalchemy_ that had to be\ndesigned and built on top of marshmallow_.\n\n.. _SQLAlchemy: www.sqlalchemy.org\n.. _marshmallow-sqlalchemy: http://marshmallow-sqlalchemy.readthedocs.io\n.. _marshmallow: https://marshmallow.readthedocs.io\n.. _Flask-RESTAlchemy: https://github.com/ESSS/flask-restalchemy\n\nHow to Use it\n-------------\n\nSerializing Generic Types\n.........................\n\nSuppose we have an `Employee` SQLAlchemy_ model declared:\n\n.. code-block:: python\n\n class Employee(Base):\n __tablename__ = \"Employee\"\n\n id = Column(Integer, primary_key=True)\n fullname = Column(String)\n admission = Column(DateTime, default=datetime(2000, 1, 1))\n company_id = Column(ForeignKey(\"Company.id\"))\n company = relationship(Company)\n company_name = column_property(\n select([Company.name]).where(Company.id == company_id)\n )\n password = Column(String)\n\n`Generic Types`_ are automatically serialized by `ModelSerializer`:\n\n.. code-block:: python\n\n from serialchemy import ModelSerializer\n\n emp = Employee(fullname=\"Roberto Silva\", admission=datetime(2019, 4, 2))\n\n serializer = ModelSerializer(Employee)\n serializer.dump(emp)\n\n # >>\n {\n \"id\": None,\n \"fullname\": \"Roberto Silva\",\n \"admission\": \"2019-04-02T00:00:00\",\n \"company_id\": None,\n \"company_name\": None,\n \"password\": None,\n }\n\nNew items can be deserialized by the same serializer:\n\n.. code-block:: python\n\n new_employee = {\"fullname\": \"Jobson Gomes\", \"admission\": \"2018-02-03\"}\n serializer.load(new_employee)\n\n # >> <Employee object at 0x000001C119DE3940>\n\nSerializers do not commit into the database. You must do this by yourself:\n\n.. code-block:: python\n\n emp = serializer.load(new_employee)\n session.add(emp)\n session.commit()\n\n.. _`Generic Types`: https://docs.sqlalchemy.org/en/rel_1_2/core/type_basics.html#generic-types\n\nCustom Serializers\n..................\n\nFor anything beyond `Generic Types`_ we must extend the `ModelSerializer` class:\n\n.. code-block:: python\n\n class EmployeeSerializer(ModelSerializer):\n\n password = Field(load_only=True) # passwords should be only deserialized\n company = NestedModelField(Company) # dump company as nested object\n\n\n serializer = EmployeeSerializer(Employee)\n serializer.dump(emp)\n # >>\n {\n \"id\": 1,\n \"fullname\": \"Roberto Silva\",\n \"admission\": \"2019-04-02T00:00:00\",\n \"company\": {\"id\": 3, \"name\": \"Acme Co\"},\n }\n\n\nExtend Polymorphic Serializer\n+++++++++++++++++++++++++++++\nOne of the possibilities is to serialize SQLalchemy joined table inheritance and\nit child tables as well. To do such it's necessary to set a variable with\nthe desired model class name. Take this `Employee` class with for instance and let us\nassume it have a joined table inheritance:\n\n.. code-block:: python\n\n class Employee(Base):\n ...\n type = Column(String(50))\n\n __mapper_args__ = {\"polymorphic_identity\": \"employee\", \"polymorphic_on\": type}\n\n\n class Engineer(Employee):\n __tablename__ = \"Engineer\"\n id = Column(Integer, ForeignKey(\"employee.id\"), primary_key=True)\n association = relationship(Association)\n\n __mapper_args__ = {\n \"polymorphic_identity\": \"engineer\",\n }\n\nTo use a extended `ModelSerializer` class on the `Engineer` class, you should create\nthe serializer as it follows:\n\n.. code-block:: python\n\n class EmployeeSerializer(\n PolymorphicModelSerializer\n ): # Since this class will be polymorphic\n\n password = Field(load_only=True)\n company = NestedModelField(Company)\n\n\n class EngineerSerializer(EmployeeSerializer):\n __model_class__ = Engineer # This is the table Serialchemy will refer to\n association = NestedModelField(Association)\n\nContributing\n------------\n\nFor guidance on setting up a development environment and how to make a\ncontribution to serialchemy, see the `contributing guidelines`_.\n\n.. _contributing guidelines: https://github.com/ESSS/serialchemy/blob/master/CONTRIBUTING.rst\n\n\nRelease\n-------\nA reminder for the maintainers on how to make a new release.\n\nNote that the VERSION should folow the semantic versioning as X.Y.Z\nEx.: v1.0.5\n\n1. Create a ``release-VERSION`` branch from ``upstream/master``.\n2. Update ``CHANGELOG.rst``.\n3. Push a branch with the changes.\n4. Once all builds pass, push a ``VERSION`` tag to ``upstream``.\n5. Merge the PR.\n\n\nHistory\n=======\n\n0.4.0 (2013-12-11)\n------------------\n* Fix to get model attribute name instead of table column name on polymorphic serializer\n* Extends the PolymorphicModelSerializer to accept also column descriptors when searching\n for the polymorphic column key.\n* Add support for serialization of Python Enums\n* Change PolymorphicModelSerializer to support inherited models of inherited models\n* Change Field to use a default serializer for not None values\n* Added support for sqlalchemy 1.4\n* Add EnumKeySerializer\n\n\nHistory\n=======\n\n0.4.0 (2013-12-11)\n------------------\n* Fix to get model attribute name instead of table column name on polymorphic serializer\n* Extends the PolymorphicModelSerializer to accept also column descriptors when searching\n for the polymorphic column key.\n* Add support for serialization of Python Enums\n* Change PolymorphicModelSerializer to support inherited models of inherited models\n* Change Field to use a default serializer for not None values\n* Added support for sqlalchemy 1.4\n* Add EnumKeySerializer\n\n0.3.0 (2019-17-07)\n------------------\n* Add the composite fields to list of properties of model, to serialize that fields if it type is in EXTRA_SERIALIZERS.\n* Fix error for SQLAlchemy composite attributes\n* Added free functions dump and load so users can quickly dump a SQLAlchemy model without having to instancialize\n ModelSerializer.\n\n0.2.0 (2019-03-22)\n------------------\n\n* Fix: Error when deserializing of nested models when SQLAlchemy model primary\n key attribute name differs from the column name\n* Allow EXTRA_SERIALIZERS to be defined in runtime\n* Check if a session was given when serializing/deserializing nested fields\n\n0.1.0 (2019-02-12)\n------------------\n\n* First release on PyPI.\n",
"bugtrack_url": null,
"license": "MIT license",
"summary": "Serializers for SQLAlchemy models.",
"version": "0.4.0",
"project_urls": {
"Homepage": "https://github.com/ESSS/serialchemy"
},
"split_keywords": [
"serialchemy"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "59e3c8cca9c5cfaed3de3c9647b88e17acc25bc508cb485f3e186d857edeffeb",
"md5": "13680b531e18dfae3ed8efc1660ae969",
"sha256": "8649e5a95fbe453c382bc346ab8a9dc6226a9353e3c4e316b7432f03eaffbd61"
},
"downloads": -1,
"filename": "serialchemy-0.4.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "13680b531e18dfae3ed8efc1660ae969",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 30692,
"upload_time": "2023-11-10T21:19:59",
"upload_time_iso_8601": "2023-11-10T21:19:59.627574Z",
"url": "https://files.pythonhosted.org/packages/59/e3/c8cca9c5cfaed3de3c9647b88e17acc25bc508cb485f3e186d857edeffeb/serialchemy-0.4.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "04736cae80eef269aeca098de9443c401c9515fc0fd48d7ff590e987270aa720",
"md5": "986838d8247a86f0dde699f77fc0c0bb",
"sha256": "ce323692936de35b7ba0525dd60e4c877cd22cf3a3dd8e2d89ae712c2d5c5591"
},
"downloads": -1,
"filename": "serialchemy-0.4.0.tar.gz",
"has_sig": false,
"md5_digest": "986838d8247a86f0dde699f77fc0c0bb",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 27126,
"upload_time": "2023-11-10T21:20:01",
"upload_time_iso_8601": "2023-11-10T21:20:01.142442Z",
"url": "https://files.pythonhosted.org/packages/04/73/6cae80eef269aeca098de9443c401c9515fc0fd48d7ff590e987270aa720/serialchemy-0.4.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-11-10 21:20:01",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ESSS",
"github_project": "serialchemy",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "serialchemy"
}