Basic objects

The basic objects of SQLAlchemy-Mutable are:

  1. MutableModelBase. Base class for database models with MutableType columns.
  2. MutableType. Column type associated with Mutable objects.
  3. Mutable. Generic mutable object which automatically tracks changes to its attributes and items.

sqlalchemy_mutable.MutableModelBase

Base class for database models with MutableType columns. This allows you to store and retrieve database models in MutableType columns.

Examples

Make sure you have run the setup code.

model0 = MyModel()
model1 = MyModel()
session.add_all([model0, model1])
session.commit()
model0.mutable = model1
# without subclassing `MutableModelBase`,
# this would not retrieve `model1`
model0.mutable

Out:

<__main__.MyModel at 0x7f6bd9936668>

sqlalchemy_mutable.MutableType

Mutable column type with pickle serialization. MutableType columns may be set to:

  1. Coerced types. SQLAlchemy-Mutable automatically coerces common objects such as int, str, and datetime.
  2. Mutable objects. SQLAlchemy-Mutable automatically converts list and dict to mutable objects.
  3. Database models.

sqlalchemy_mutable.MutableJSONType

Mutable column type with JSON serialization. MutableJSONType columns may be set to lists, dictionaries, and common literals which are JSON serializable.

sqlalchemy_mutable.Mutable

Base class for mutable objects. Mutable objects track changes to their 'children' (their attributes and items).

Attributes: root : sqlalchemy_mutable.Mutable

Root mutable object.

Examples

Make sure you have run the setup code.

model = MyModel()
session.add(model)
model.mutable.nested_mutable = Mutable()
session.commit()
# if `MyModel.mutable` weren't a `MutableType` column,
# this change would not survive a commit
model.mutable.nested_mutable.greeting = 'hello world'
session.commit()
model.mutable.nested_mutable.greeting

Out:

'hello, world!'

Methods

register_coerced_type(cls, origin_type) [source]

Decorator for coerced type registration.

When a MutableType column is set to an object of the origin type (i.e. when the coerce method is invoked), the object is first converted to a coerced type.

Parameters: origin_type : class

The origin class.

Returns: register : callable

Function to register an origin type.

Notes

This does not affect tracked items and attributes. That is, objects of origin types will not be coerced with the _convert method is invoked.

Examples

Make sure you have run the setup code.

class MyClass():
    def greet(self, name='world'):
        return 'hello, {}!'.format(name)

@Mutable.register_coerced_type(MyClass)
class CoercedMyClass(Mutable, MyClass):
    pass

model = MyModel()
# without registering an associated coerced type,
# this will throw an error
model.mutable = MyClass()
model.mutable.greet()

Out:

'hello, world!'

register_tracked_type(cls, origin_type) [source]

Decorator for tracked type registration.

The origin_type maps to a tracked_type. Objects of origin types will be converted to objects of tracked types when the convert method is invoked. Conversion occurs automatically on coersion and when setting attributes and items.

Parameters: origin_type : class

The origin class.

Returns: register : callable

Function to register an origin type.

Examples

Make sure you have run the setup code.

class MyClass():
    def __init__(self, name):
        self.name = name

    def greet(self):
        return 'hello, {}!'.format(self.name)

@Mutable.register_tracked_type(MyClass)
class MutableMyClass(MyClass, Mutable):
    def __init__(self, source=None, root=None):
        '''
        Parameters
        ----------
        source : MyClass
            Original instance of `MyClass`. This will be converted
            into a `MutableMyClass` object.

        root : Mutable or None, default=None
            Root mutable object. This is handled by
            SQLAlchemy-Mutable. Set to `None` by default.
        '''
        super().__init__(name=source.name)

model = MyModel()
session.add(model)
model.mutable = Mutable()
model.mutable.object = MyClass('world')
session.commit()
# without registering MyClass as a tracked type,
# this change would not survive a commit
model.mutable.object.name = 'moon'
session.commit()
model.mutable.object.greet()

Out:

'hello, moon!'