Metadata-Version: 1.0
Name: SQLAlchemy-serializer
Version: 1.1.3
Summary: Mixin for SQLAlchemy-models serialization without pain
Home-page: https://github.com/n0nSmoker/SQLAlchemy-serializer.git
Author: Y-Bro
Author-email: UNKNOWN
License: UNKNOWN
Description: # SQLAlchemy-serializer
        Mixin for sqlalchemy-models serialization without pain.
        
        ## Installation
        
        ```
        pip install SQLAlchemy-serializer
        ```
        
        ## Usage
        
        If you want SQLAlchemy model to become serializable,
        add **SerializerMixin** in class definition:
        ```python
        from sqlalchemy_serializer import SerializerMixin
        
        
        class SomeModel(db.Model, SerializerMixin):
            ...
        ```
        
        This mixin adds **.to_dict()** method to model instances.
        So now you can do something like this:
        ```python
        item = SomeModel.query.filter(.....).one()
        result = item.to_dict()
        ```
        You'll get values of all SQLAlchemy fields in the `result` var, even nested relationships
        
        If you want to exclude a few fields for this exact item:
        ```python
        result = item.to_dict(rules=('-somefield', '-anotherone.nested1.nested2'))
        ```
        
        If you want to add a field which is not defined as an SQLAlchemy field:
        ```python
        class SomeModel(db.Model, SerializerMixin):
            non_sql_field = 123
        
            def method(self):
                return anything
        
        result = item.to_dict(rules=('non_sql_field', 'method'))
        ```
        Note that method or a function should have no arguments except ***self***,
        in order to let serializer call it without hesitations.
        
        If you want to get exact fields:
        ```python
        
        result = item.to_dict(only=('non_sql_field', 'method', 'somefield'))
        ```
        Note that if ***somefield*** is an SQLAlchemy instance, you get all it's
        serializable fields.
        
        If you want to define schema for all instances of particular SQLAlchemy model,
        add serialize properties to model definition:
        
        ```python
        class SomeModel(db.Model, SerializerMixin):
            serialize_only = ('somefield.id',)
            serialize_rules = ()
            ...
            somefield = db.relationship('AnotherModel')
        
        result = item.to_dict()
        {'somefield':[{'id':...}]}
        
        ```
        ***serialize_only*** and  ***serialize_rules*** work the same way as ***to_dict's*** arguments
        
        
        # Detailed example (For more examples see tests):
        
        ```python
        class FlatModel(db.Model, SerializerMixin):
            """
            to_dict() of all instances of this model now returns only following two fields
            """
            serialize_only = ('non_sqlalchemy_field', 'id')
            serialize_rules = ()
        
            id = db.Column(db.Integer, primary_key=True)
            string = db.Column(db.String(256), default='Some string!')
            time = db.Column(db.DateTime, default=datetime.utcnow())
            date = db.Column(db.Date, default=datetime.utcnow())
            boolean = db.Column(db.Boolean, default=True)
            boolean2 = db.Column(db.Boolean, default=False)
            null = db.Column(db.String)
            non_sqlalchemy_dict = dict(qwerty=123)
        
        
        class ComplexModel(db.Model, SerializerMixin):
           """
           Schema is not defined so
           we will get all SQLAlchemy attributes of the instance by default
           """
        
            id = db.Column(db.Integer, primary_key=True)
            string = db.Column(db.String(256), default='Some string!')
            boolean = db.Column(db.Boolean, default=True)
            null = db.Column(db.String)
            flat_id = db.Column(db.ForeignKey('test_flat_model.id'))
            rel = db.relationship('FlatModel')
            non_sqlalchemy_list = [dict(a=12, b=10), dict(a=123, b=12)]
        
        instance = ComplexModel.query.first()
        
        
        # Now by default the result looks like this:
        
        instance.to_dict()
        dict(
            id=1,
            string='Some string!',
            boolean=True,
            null=None,
            flat_id=1,
            rel=[dict(
                id=1,
                non_sqlalchemy_dict=dict(qwerty=123)
            )]
        
        
        # Extend schema
        
        instance.to_dict(rules=('-id', '-rel.id', 'rel.string', 'non_sqlalchemy_list'))
        
        dict(
            string='Some string!',
            boolean=True,
            null=None,
            flat_id=1,
            non_sqlalchemy_list=[dict(a=12, b=10), dict(a=123, b=12)],
            rel=dict(
                string='Some string!',
                non_sqlalchemy_dict=dict(qwerty=123)
        )
        
        
        # Exclusive schema
        
        instance.to_dict(only=('id', 'flat_id', 'rel.id', 'non_sqlalchemy_list.a'))
        
        dict(
            id=1,
            flat_id=1,
            non_sqlalchemy_list=[dict(a=12), dict(a=123)],
            rel=dict(
                id=1
            )
        
        ```
        
        # Customisation
        If you want to set default behavior for every model you should write
        your own mixin class like above
        
        ```python
        from sqlalchemy_serializer import SerializerMixin
        
        
        class CustomMixin(SerializerMixin):
            serialize_only = ()   # Define custom schema here if needed
            serialize_rules = ()  # Define custom schema here if needed
        
            date_format = '%Y-%m-%d'  # Define custom format here if needed
            datetime_format = '%Y-%m-%d %H:%M'  # Define custom format here if needed
            time_format = '%H:%M'  # Define custom format here if needed
        
            def get_tzinfo(self):
                """
                Callback to make serializer aware of user's timezone. Should be redefined if needed
                :return: datetime.tzinfo
                """
                return None
        
        ```
        
        # Troubleshooting
        If you've faced with 'maximum recursion depth exceeded' exception,
        most likely serializer have found instance of the same class somewhere among model's relationships.
        You need to exclude it from schema or specify the exact properties to serialize.
        
        
        
        # Tests
        To run tests and see tests coverage report just type the following command
        
        ```
        make test
        ```
        
        
Keywords: sqlalchemy,serialize,to_dict,JSON
Platform: UNKNOWN
