serialchemy


Nameserialchemy JSON
Version 0.4.0 PyPI version JSON
download
home_pagehttps://github.com/ESSS/serialchemy
SummarySerializers for SQLAlchemy models.
upload_time2023-11-10 21:20:01
maintainer
docs_urlNone
authorESSS
requires_python>=3.6
licenseMIT license
keywords serialchemy
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ======================================================================
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"
}
        
Elapsed time: 0.13320s