Configuration

Global and class level configuration

All Continuum configuration parameters can be set on global level (manager level) and on class level. Setting an option at manager level affects all classes within the scope of the manager’s class instrumentation listener (by default all SQLAlchemy declarative models).

In the following example we set ‘transaction_column_name’ configuration option to False at the manager level.

make_versioned(options={'transaction_column_name': 'my_tx_id'})

As the name suggests class level configuration only applies to given class. Class level configuration can be passed to __versioned__ class attribute.

class User(Base):
    __versioned__ = {
        'transaction_column_name': 'tx_id'
    }

Versioning strategies

Similar to Hibernate Envers SQLAlchemy-Continuum offers two distinct versioning strategies ‘validity’ and ‘subquery’. The default strategy is ‘validity’.

Validity

The ‘validity’ strategy saves two columns in each history table, namely ‘transaction_id’ and ‘end_transaction_id’. The names of these columns can be configured with configuration options transaction_column_name and end_transaction_column_name.

As with ‘subquery’ strategy for each inserted, updated and deleted entity Continuum creates new version in the history table. However it also updates the end_transaction_id of the previous version to point at the current version. This creates a little bit of overhead during data manipulation.

With ‘validity’ strategy version traversal is very fast. When accessing previous version Continuum tries to find the version record where the primary keys match and end_transaction_id is the same as the transaction_id of the given version record. When accessing the next version Continuum tries to find the version record where the primary keys match and transaction_id is the same as the end_transaction_id of the given version record.

Pros:
  • Version traversal is much faster since no correlated subqueries are needed
Cons:
  • Updates, inserts and deletes are little bit slower

Subquery

The ‘subquery’ strategy uses one column in each history table, namely ‘transaction_id’. The name of this column can be configured with configuration option transaction_column_name.

After each inserted, updated and deleted entity Continuum creates new version in the history table and sets the ‘transaction_id’ column to point at the current transaction.

With ‘subquery’ strategy the version traversal is slow. When accessing previous and next versions of given version object needs correlated subqueries.

Pros:
  • Updates, inserts and deletes little bit faster than in ‘validity’ strategy
Cons:
  • Version traversel much slower

Column exclusion and inclusion

With exclude configuration option you can define which entity attributes you want to get versioned. By default Continuum versions all entity attributes.

class User(Base):
    __versioned__ = {
        'exclude': ['picture']
    }

    id = sa.Column(sa.Integer, primary_key=True)
    name = sa.Column(sa.Unicode(255))
    picture = sa.Column(sa.LargeBinary)

Basic configuration options

Here is a full list of configuration options:

  • base_classes (default: None)
    A tuple defining history class base classes.
  • table_name (default: ‘%s_version’)
    The name of the history table.
  • transaction_column_name (default: ‘transaction_id’)
    The name of the transaction column (used by history tables).
  • end_transaction_column_name (default: ‘end_transaction_id’)
    The name of the end transaction column in history table when using the validity versioning strategy.
  • operation_type_column_name (default: ‘operation_type’)
    The name of the operation type column (used by history tables).
  • strategy (default: ‘validity’)
    The versioning strategy to use. Either ‘validity’ or ‘subquery’

Example

class Article(Base):
    __versioned__ = {
        'transaction_column_name': 'tx_id'
    }
    __tablename__ = 'user'

    id = sa.Column(sa.Integer, primary_key=True, autoincrement=True)
    name = sa.Column(sa.Unicode(255))
    content = sa.Column(sa.UnicodeText)

Customizing transaction user class

By default Continuum tries to build a relationship between ‘User’ class and Transaction class. If you have differently named user class you can simply pass its name to make_versioned:

make_versioned(user_cls='MyUserClass')

If you don’t want transactions to contain any user references you can also disable this feature.

make_versioned(user_cls=None)

Customizing versioned mappers

By default SQLAlchemy-Continuum versions all mappers. You can override this behaviour by passing the desired mapper class/object to make_versioned function.

make_versioned(mapper=my_mapper)

Customizing versioned sessions

By default SQLAlchemy-Continuum versions all sessions. You can override this behaviour by passing the desired session class/object to make_versioned function.

make_versioned(session=my_session)