API Documentation
*****************

sqlalchemy_continuum.make_versioned(mapper=<class 'sqlalchemy.orm.mapper.Mapper'>, session=<class 'sqlalchemy.orm.session.Session'>, manager=<sqlalchemy_continuum.manager.VersioningManager object>, plugins=None, options=None, user_cls='User')

   This is the public API function of SQLAlchemy-Continuum for making
   certain mappers and sessions versioned. By default this applies to
   all mappers and all sessions.

   Parameters:
      * **mapper** -- SQLAlchemy mapper to apply the versioning to.

      * **session** -- SQLAlchemy session to apply the versioning to.
        By default this is sa.orm.session.Session meaning it applies
        to all Session subclasses.

      * **manager** -- SQLAlchemy-Continuum versioning manager.

      * **plugins** -- Plugins to pass for versioning manager.

      * **options** -- A dictionary of VersioningManager options.

      * **user_cls** -- User class which the Transaction class should
        have relationship to. This can either be a class or string
        name of a class for lazy evaluation.


Versioning Manager
==================

class sqlalchemy_continuum.VersioningManager(unit_of_work_cls=<class 'sqlalchemy_continuum.unit_of_work.UnitOfWork'>, transaction_cls=None, user_cls=None, options=None, plugins=None, builder=None)

   VersioningManager delegates versioning configuration operations to
   builder classes and the actual versioning to UnitOfWork class.
   Manager contains configuration options that act as defaults for all
   versioned classes.

   Parameters:
      * **unit_of_work_cls** -- The UnitOfWork class to use for
        initializing UnitOfWork objects for versioning

      * **transaction_cls** -- Transaction class to use for
        versioning. If None, the default Transaction class generated
        by TransactionFactory will be used.

      * **user_cls** -- User class which Transaction class should have
        relationship to. This can either be a class or string name of
        a class for lazy evaluation.

      * **options** -- Versioning options

      * **plugins** -- Versioning plugins that listen the events
        invoked by the manager.

      * **builder** -- Builder object which handles the building of
        versioning tables and models.

   after_flush(session, flush_context)

      After flush listener for SQLAlchemy sessions. If this manager
      has versioning enabled this listener gets the UnitOfWork
      associated with session's connections and invokes the
      process_after_flush method of that object.

      Parameters:
         **session** -- SQLAlchemy session

   append_association_operation(conn, table_name, params, op)

      Append history association operation to pending_statements list.

   apply_class_configuration_listeners(mapper)

      Applies class configuration listeners for given mapper.

      The listener work in two phases:

      1. Class instrumentation phase
            The first listeners listens to class instrumentation event
            and handles the collecting of versioned models and adds
            them to the pending_classes list.

      2. After class configuration phase
            The second listener listens to after class configuration
            event and handles the actual history model generation
            based on list that was collected during class
            instrumenation phase.

      Parameters:
         **mapper** -- SQLAlchemy mapper to apply the class
         configuration listeners to

   before_flush(session, flush_context, instances)

      Before flush listener for SQLAlchemy sessions. If this manager
      has versioning enabled this listener invokes the process before
      flush of associated UnitOfWork object.

      Parameters:
         **session** -- SQLAlchemy session

   clear(session)

      Simple SQLAlchemy listener that is being invoked after
      successful transaction commit or when transaction rollback
      occurs. The purpose of this listener is to reset this UnitOfWork
      back to its initialization state.

      Parameters:
         **session** -- SQLAlchemy session object

   create_transaction_model()

      Create Transaction class but only if it doesn't already exist in
      declarative model registry.

   is_excluded_property(model, key)

      Returns whether or not given property of given model is excluded
      from the associated history model.

      Parameters:
         * **model** -- SQLAlchemy declarative model object.

         * **key** -- Model property key

   option(model, name)

      Returns the option value for given model. If the option is not
      found from given model falls back to default values of this
      manager object. If the option is not found from this manager
      object either this method throws a KeyError.

      Parameters:
         * **model** -- SQLAlchemy declarative object

         * **name** -- name of the versioning option

   remove_class_configuration_listeners(mapper)

      Remove versioning class configuration listeners from specified
      mapper.

      Parameters:
         **mapper** -- mapper to remove class configuration listeners
         from

   remove_operations_tracking(mapper)

      Remove listeners from specified mapper that track SQL inserts,
      updates and deletes.

      Parameters:
         **mapper** -- mapper to remove the SQL operations tracking
         listeners from

   remove_session_tracking(session)

      Remove listeners that track the operations (flushing, committing
      and rolling back) of given session. This method should be used
      in conjunction with *remove_operations_tracking*.

      Parameters:
         **session** -- SQLAlchemy session to remove the operations
         tracking from

   reset()

      Resets this manager's internal state.

      This method should be used in test cases that create models on
      the fly. Otherwise history_class_map and some other variables
      would be polluted by no more used model classes.

   track_cloned_connections(c, opt)

      Track cloned connections from association tables.

   track_deletes(uow, target)

      Track object deletion operations. Whenever object is deleted it
      is added to this UnitOfWork's internal operations dictionary.

   track_inserts(uow, target)

      Track object insert operations. Whenever object is inserted it
      is added to this UnitOfWork's internal operations dictionary.

   track_operations(mapper)

      Attach listeners for specified mapper that track SQL inserts,
      updates and deletes.

      Parameters:
         **mapper** -- mapper to track the SQL operations from

   track_session(session)

      Attach listeners that track the operations (flushing, committing
      and rolling back) of given session. This method should be used
      in conjunction with *track_operations*.

      Parameters:
         **session** -- SQLAlchemy session to track the operations
         from

   track_updates(uow, target)

      Track object update operations. Whenever object is updated it is
      added to this UnitOfWork's internal operations dictionary.

   unit_of_work(session)

      Return the associated SQLAlchemy-Continuum UnitOfWork object for
      given SQLAlchemy session object.

      If no UnitOfWork object exists for given object then this method
      tries to create one.

      Parameters:
         **session** -- SQLAlchemy session object


Builders
========

class sqlalchemy_continuum.table_builder.TableBuilder(versioning_manager, parent_table, model=None)

   TableBuilder handles the building of version tables based on parent
   table's structure and versioning configuration options.

   property table_name

      Returns the version table name for current parent table.

class sqlalchemy_continuum.model_builder.ModelBuilder(versioning_manager, model)

   VersionedModelBuilder handles the building of Version models based
   on parent table attributes and versioning configuration.

   base_classes()

      Returns all base classes for history model.

   build_model(table)

      Build history model class.

   build_parent_relationship()

      Builds a relationship between currently built version class and
      parent class (the model whose history the currently build
      version class represents).

   build_transaction_relationship(tx_class)

      Builds a relationship between currently built version class and
      Transaction class.

      Parameters:
         **tx_class** -- Transaction class

   inheritance_args(cls, version_table, table)

      Return mapper inheritance args for currently built history
      model.

class sqlalchemy_continuum.relationship_builder.RelationshipBuilder(versioning_manager, model, property_)

   association_subquery(obj)

      Returns an EXISTS clause that checks if an association exists
      for given SQLAlchemy declarative object. This query is used by
      many_to_many_criteria method.

      Example query:

      EXISTS (
         SELECT 1 FROM article_tag_version WHERE article_id = 3 AND
         tag_id = tags_version.id AND operation_type != 2 AND EXISTS (

            SELECT 1 FROM article_tag_version as article_tag_version2
            WHERE article_tag_version2.tag_id =
            article_tag_version.tag_id AND article_tag_version2.tx_id
            <=5 AND article_tag_version2.article_id = 3 GROUP BY
            article_tag_version2.tag_id HAVING

               MAX(article_tag_version2.tx_id) =
               article_tag_version.tx_id

         )

      )

      Parameters:
         **obj** -- SQLAlchemy declarative object

   build_association_version_tables()

      Builds many-to-many association version table for given
      property. Association version tables are used for tracking
      change history of many-to-many associations.

   many_to_many_criteria(obj)

      Returns the many-to-many query.

      Looks up remote items through associations and for each item
      returns returns the last version with a transaction less than or
      equal to the transaction of *obj*. This must hold true for both
      the association and the remote relation items.


      Example
      -------

      Select all tags of article with id 3 and transaction 5

      SELECT tags_version.* FROM tags_version WHERE EXISTS (

         SELECT 1 FROM article_tag_version WHERE article_id = 3 AND
         tag_id = tags_version.id AND operation_type != 2 AND EXISTS (

            SELECT 1 FROM article_tag_version as article_tag_version2
            WHERE article_tag_version2.tag_id =
            article_tag_version.tag_id AND article_tag_version2.tx_id
            <= 5 GROUP BY article_tag_version2.tag_id HAVING

               MAX(article_tag_version2.tx_id) =
               article_tag_version.tx_id

         )

      ) AND EXISTS (

         SELECT 1 FROM tags_version as tags_version_2 WHERE
         tags_version_2.id = tags_version.id AND tags_version_2.tx_id
         <= 5 GROUP BY tags_version_2.id HAVING
         MAX(tags_version_2.tx_id) = tags_version.tx_id

      ) AND operation_type != 2

   many_to_one_criteria(obj)

      Returns the many-to-one query.

      Returns the item on the 'one' side with the highest transaction
      id as long as it is less or equal to the transaction id of the
      *obj*.


      Example
      -------

      Look up the Article of a Tag with article_id = 4 and
      transaction_id = 5

      SELECT * FROM articles_version WHERE id = 4 AND transaction_id =
      (

         SELECT max(transaction_id) FROM articles_version WHERE
         transaction_id <= 5 AND id = 4

      ) AND operation_type != 2

   one_to_many_criteria(obj)

      Returns the one-to-many query.

      For each item on the 'many' side, returns its latest version as
      long as the transaction of that version is less than equal of
      the transaction of *obj*.


      Example
      -------

      Using the Article-Tags relationship, where we look for tags of
      article_version with id = 3 and transaction = 5 the sql produced
      is

      SELECT tags_version.* FROM tags_version WHERE
      tags_version.article_id = 3 AND tags_version.operation_type != 2
      AND EXISTS (

         SELECT 1 FROM tags_version as tags_version_last WHERE
         tags_version_last.transaction_id <= 5 AND
         tags_version_last.id = tags_version.id GROUP BY
         tags_version_last.id HAVING

            MAX(tags_version_last.transaction_id) =
            tags_version.transaction_id

      )

   process_query(query)

      Process given SQLAlchemy Query object depending on the
      associated RelationshipProperty object.

      Parameters:
         **query** -- SQLAlchemy Query object

   property reflected_relationship

      Builds a reflected one-to-many, one-to-one and many-to-one
      relationship between two version classes.


UnitOfWork
==========

class sqlalchemy_continuum.unit_of_work.UnitOfWork(manager)

   assign_attributes(parent_obj, version_obj)

      Assign attributes values from parent object to version object.

      Parameters:
         * **parent_obj** -- Parent object to get the attribute values
           from

         * **version_obj** -- Version object to assign the attribute
           values to

   create_association_versions(session)

      Creates association table version records for given session.

      Parameters:
         **session** -- SQLAlchemy session object

   create_transaction(session)

      Create transaction object for given SQLAlchemy session.

      Parameters:
         **session** -- SQLAlchemy session object

   create_version_objects(session)

      Create version objects for given session based on operations
      collected by insert, update and deleted trackers.

      Parameters:
         **session** -- SQLAlchemy session object

   get_or_create_version_object(target)

      Return version object for given parent object. If no version
      object exists for given parent object, create one.

      Parameters:
         **target** -- Parent object to create the version object for

   property has_changes

      Return whether or not this unit of work has changes.

   is_modified(session)

      Return whether or not given session has been modified. Session
      has been modified if any versioned property of any version
      object in given session has been modified or if any of the
      plugins returns that session has been modified.

      Parameters:
         **session** -- SQLAlchemy session object

   make_versions(session)

      Create transaction, transaction changes records, version
      objects.

      Parameters:
         **session** -- SQLAlchemy session object

   process_after_flush(session)

      After flush processor for given session.

      Creates version objects for all modified versioned parent
      objects that were affected during the flush phase.

      Parameters:
         **session** -- SQLAlchemy session object

   process_before_flush(session)

      Before flush processor for given session.

      This method creates a version session which is later on used for
      the creation of version objects. It also creates Transaction
      object for the current transaction and invokes before_flush
      template method on all plugins.

      If the given session had no relevant modifications regarding
      versioned objects this method does nothing.

      Parameters:
         **session** -- SQLAlchemy session object

   process_operation(operation)

      Process given operation object. The operation processing has x
      stages:

      1. Get or create a version object for given parent object

      2. Assign the operation type for this object

      3. Invoke listeners

      4. Update version validity in case validity strategy is used

      5. Mark operation as processed

      Parameters:
         **operation** -- Operation object

   reset(session=None)

      Reset the internal state of this UnitOfWork object. Normally
      this is called after transaction has been committed or rolled
      back.

   update_version_validity(parent, version_obj)

      Updates previous version object end_transaction_id based on
      given parent object and newly created version object.

      This method is only used when using 'validity' versioning
      strategy.

      Parameters:
         **parent** -- SQLAlchemy declarative parent object

      Parem version_obj:
         SQLAlchemy declarative version object

      See also: "version_validity_subquery()"

   version_validity_subquery(parent, version_obj, alias=None)

      Return the subquery needed by "update_version_validity()".

      This method is only used when using 'validity' versioning
      strategy.

      Parameters:
         **parent** -- SQLAlchemy declarative parent object

      Parem version_obj:
         SQLAlchemy declarative version object

      See also: "update_version_validity()"


History class
=============

class sqlalchemy_continuum.version.VersionClassBase

   property changeset

      Return a dictionary of changed fields in this version with keys
      as field names and values as lists with first value as the old
      field value and second list value as the new value.

   property index

      Return the index of this version in the version history.

   property next

      Returns the next version relative to this version in the version
      history. If current version is the last version this method
      returns None.

   property previous

      Returns the previous version relative to this version in the
      version history. If current version is the first version this
      method returns None.


Changelog
=========

Here you can see the full list of changes between each SQLAlchemy-
Continuum release.


Unreleased changes
------------------

* None currently


1.5.2 (2025-10-10)
------------------

* Add Python 3.14 support


1.5.1 (2025-10-01)
------------------

* Fix utc_now() to return a naive datetime (#373, thanks to dawhalen)


1.5.0 (2025-08-30)
------------------

* Migrate to ruff for code linting and formatting, replacing flake8
  with a faster Rust-based tool. (#364)

* Add Python 3.13 support. (#364)

* Drop Python 3.8 support. (#364)

* Add comprehensive pre-commit hooks configuration with ruff,
  pyupgrade, and code quality checks

* Add pyupgrade integration to automatically modernize Python 3.9+
  syntax

* Enhance tox configuration with matrix testing for multiple Python
  (3.9-3.13) and SQLAlchemy versions (1.4, 2.x)

* Add dedicated ruff testing environment in tox for consistent code
  quality checks

* Modernize codebase with Python 3.9+ idioms and formatting
  improvements

* Migrate to modern Python packaging with pyproject.toml

* Remove SQLAlchemy-i18n support

* Fix SQLAlchemy 2.0 deprecation warnings: replace Query.get() with
  Session.get() for improved compatibility

* Fix datetime.utcnow() deprecation warnings with cross-version
  compatibility function supporting Python 3.9-3.13+

* Eliminate cartesian product warnings in many-to-many relationship
  queries with non-versioned classes

* Improve code quality by modernizing mixed string formatting patterns
  to f-strings

* **MAJOR**: Remove SQLAlchemy-Utils dependency by porting required
  functions to internal _compat module (#352)

  * Port core functions: ImproperlyConfigured, get_declarative_base,
    naturally_equivalent

  * Port column utilities: get_columns, get_primary_keys, identity,
    get_column_key

  * Port advanced functionality: has_changes, JSONType,
    generic_relationship with full SQLAlchemy 2.x compatibility

  * Maintain full backward compatibility while eliminating external
    dependency

  * Reduce installation footprint and potential version conflicts


1.4.2 (2024-03-26)
------------------

* Remove SQLAlchemy pin and require latest SQLAlchemy-Utils


1.4.1 (2024-03-14)
------------------

* Pin SQLAlchemy due to SQLAlchemy-Utils breakage

* Fix docs (#335, thanks to gnu-lorien)

* Remove use of deprecated *_app_ctx_stack* and *_request_ctx_stack*
  (#307, thanks to rubencho)


1.4.0 (2023-07-12)
------------------

* Add support for SQLAlchemy 2.0

* Remove compatibility code for SQLAlchemy < 1.4 and Python 2

* Fix deadlock issues in MySQL on concurrent inserts (#172, thanks to
  mfulgo)

* Allow overriding of DATABASE_URL for docker compose

* Switch to before_execute for association tracking

* Use ORM instead of deadlock-prone validity update query

* create_trigger and sync_trigger now take a session, not a connection

* Removed Operation.iteritems


1.3.15 (2023-06-07)
-------------------

* Fix docs (#329, thanks to kelvinscuesta)

* Declare six as a dependency (#327, thanks to zupo)


1.3.14 (2023-01-04)
-------------------

* Undo unneeded change to Flask-Login that breaks alternative IDs
  (#325, thanks to anthraxx)


1.3.13 (2022-09-07)
-------------------

* Fixes for Flask 2.2 and Flask-Login 0.6.2 (#288, thanks to
  AbdealiJK)

* Allow changed_entities to work without TransactionChanges plugin
  (#268, thanks to TomGoBravo)

* Fix Activity plugin for non-composite primary keys not named id
  (#210, thanks to dryobates)

* Allow sync_trigger to pass arguments through to create_trigger
  (#273, thanks to nanvel)

* Fix association tables on Oracle (#291, thanks to AbdealiJK)

* Fix some deprecation warnings in SA 1.4 (#269, #277, #279, #300,
  #302, thanks to TomGoBravo, edhaz, and indiVar0508)


1.3.12 (2022-01-18)
-------------------

* Support SA 1.4


1.3.11 (2020-05-24)
-------------------

* Made ModelBuilder create column aliases in version models (#246,
  courtesy of killthekitten)


1.3.10 (2020-05-10)
-------------------

* Added explicit "pseudo-backref" relationships for version/parent
  (#240, courtesy of lgedgar)

* Fixed m2m Bug when an unrelated change is made to a model (#242,
  courtesy of Andrew-Dickinson)


1.3.9 (2019-03-19)
------------------

* Added SA 1.3 support

* Reverted trigger creation from 1.3.7


1.3.8 (2019-02-27)
------------------

* Fixed revert to ignore non-columns (#197, courtesy of mauler)


1.3.7 (2019-01-13)
------------------

* Fix trigger creation during alembic migrations (#209, courtesy of
  lyndsysimon)


1.3.6 (2018-07-30)
------------------

* Fixed ResourceClosedErrors from connections leaking when using an
  external transaction (#196, courtesy of vault)


1.3.5 (2018-06-03)
------------------

* Track cloned connections (#167, courtesy of netcriptus)


1.3.4 (2018-03-07)
------------------

* Exclude many-to-many properties from versioning if they are added in
  exclude parameter (#169, courtesy of fuhrysteve)


1.3.3 (2017-11-05)
------------------

* Fixed changeset when updating object in same transaction as
  inserting it (#141, courtesy of oinopion)


1.3.2 (2017-10-12)
------------------

* Fixed multiple schema handling (#132, courtesy of vault)


1.3.1 (2017-06-28)
------------------

* Fixed subclass retrieval for closest_matching_table (#163, courtesy
  of debonzi)


1.3.0 (2017-01-30)
------------------

* Dropped py2.6 support

* Fixed memory leaks with UnitOfWork instances (#131, courtesy of
  quantus)


1.2.4 (2016-01-10)
------------------

* Added explicit sequence names for Oracle (#118, courtesy of
  apfeiffer1)


1.2.3 (2016-01-10)
------------------

* Added use_module_name configuration option (#119, courtesy of kyheo)


1.2.2 (2015-12-08)
------------------

* Fixed some relationship changes not counted as modifications (#116,
  courtesy of tvuotila)


1.2.1 (2015-09-27)
------------------

* Fixed deep joined table inheritance handling (#105, courtesy of
  piotr-dobrogost)

* Fixed naive assumption of related User model always having id column
  (#107, courtesy of avilaton)

* Fixed one-to-many relationship reverting (#102, courtesy of
  sdorazio)


1.2.0 (2015-07-31)
------------------

* Removed generated changes attribute from version classes. This
  attribute can be accessed through *transaction.changes*

* Removed is_modified checking from insert operations


1.1.5 (2014-12-28)
------------------

* Added smart primary key type inspection for user class (#86,
  courtesy of mattupstate)

* Added support for self-referential version relationship reflection
  (#88, courtesy of dtheodor)


1.1.4 (2014-12-06)
------------------

* Fixed One-To-Many version relationship handling (#82, courtesy of
  dtheodor)

* Fixed Many-To-Many version relationship handling (#83, courtesy of
  dtheodor)

* Fixed inclusion and exclusion of aliased columns

* Removed automatic exclusion of auto-assigned datetime columns and
  tsvector columns (explicit is better than implicit)


1.1.3 (2014-10-23)
------------------

* Made FlaskPlugin accepts overriding of current_user_id_factory and
  remote_addr_factory


1.1.2 (2014-10-07)
------------------

* Fixed identifier quoting in trigger syncing


1.1.1 (2014-10-07)
------------------

* Fixed native versioning trigger syncing


1.1.0 (2014-10-02)
------------------

* Added Python 3.4 to test suite

* Added optional native trigger based versioning for PostgreSQL
  dialect

* Added create_models option

* Added count_versions utility function

* Fixed custom transaction column name handling with models using
  joined table inheritance

* Fixed subquery strategy support for models using joined table
  inheritance

* Fixed savepoint handling

* Fixed version model building when no versioned models were found
  (previously threw AttributeError)

* Replaced plugin template methods before_create_tx_object and
  after_create_tx_object with transaction_args to better cope with
  native versioning


1.0.3 (2014-07-16)
------------------

* Added __repr__ for Operations class

* Fixed an issue where assigning unmodified object's attributes in
  user defined before flush listener would raise TypeError in
  UnitOfWork


1.0.2 (2014-07-11)
------------------

* Allowed easier overriding of PropertyModTracker column creation

* Rewrote join table inheritance handling schematics (now working with
  SA 0.9.6)

* SQLAlchemy-Utils dependency updated to 0.26.5


1.0.1 (2014-06-18)
------------------

* Fixed an issue where deleting an object with deferred columns would
  throw ObjectDeletedError.

* Made viewonly relationships with association tables not register the
  association table to versioning manager registry.


1.0 (2014-06-16)
----------------

* Added __repr__ for Transaction class, issue #59

* Made transaction_cls of VersioningManager configurable.

* Removed generic relationships from transaction class to versioned
  classes.

* Removed generic relationships from transaction changes class to
  versioned classes.

* Removed relation_naming_function (no longer needed)

* Moved get_bind to SQLAlchemy-Utils

* Removed inflection package from dependencies (no longer needed)

* SQLAlchemy-Utils dependency updated to 0.26.2


1.0b5 (2014-05-07)
------------------

* Added order_by mapper arg ignoring for version class reflection if
  other than string argument is used

* Added support for customizing the User class which the Transaction
  class should have relationship to (issue #53)

* Changed get_versioning_manager to throw ClassNotVersioned exception
  if first argument is not a versioned class

* Fixed relationship reflection from versioned classes to non
  versioned classes (issue #52)

* SQLAlchemy-Utils dependency updated to 0.25.4


1.0-b4 (2014-04-20)
-------------------

* Fixed many-to-many unit of work inspection when using engine bind
  instead of collection bind

* Fixed various issues if primary key aliases were used in declarative
  models

* Fixed an issue where association versioning would not work with
  custom transaction column name

* SQLAlchemy-Utils dependency updated to 0.25.3


1.0-b3 (2014-04-19)
-------------------

* Added support for concrete inheritance

* Added order_by mapper arg reflection to version classes

* Added support for column_prefix mapper arg

* Made model builder copy inheritance mapper args to version classes
  from parent classes

* Fixed end transaction id setting for join table inheritance classes.
  Now end transaction id is set explicitly to all tables in
  inheritance hierarchy.

* Fixed single table inheritance handling


1.0-b2 (2014-04-09)
-------------------

* Added some schema tools to help migrating between different plugins
  and versioning strategies

* Added remove_versioning utility function, see issue #45

* Added order_by transaction_id default to versions relationship

* Fixed PropertyModTrackerPlugin association table handling.

* Fixed get_bind schematics (Flask-SQLAlchemy integration wasn't
  working)

* Fixed a bug where committing a session without objects would result
  in KeyError

* SQLAlchemy dependency updated to 0.9.4


1.0-b1 (2014-03-14)
-------------------

* Added new plugin architecture

* Added ActivityPlugin

* Naming conventions change: History -> Version (to be consistent
  throughout Continuum)

* Naming convention change: TransactionLog -> Transaction

* Rewritten reflected relationship model for version classes. Only
  dynamic relationships are now reflected as dynamic relationships.
  Other relationships return either lists or scalars.

* One-To-One relationship support for reflected version class
  relationships

* Removed tx_context context manager. Transaction objects can now be
  created manually and user has direct access to the parameters of
  this object.

* Removed tx_meta context manager. Transaction meta objects can now be
  created explicitly.

* Fixed association reverting when the relationship uses uselist=False

* Fixed one-to-many directed relationship reverting when the
  relationship uses uselist=False

* Fixed many-to-many relationship handling when multiple links were
  created during the same transaction

* Added indexes to operation_type, transaction_id and
  end_transaction_id columns of version classes

* Deprecated extensions

* SQLAlchemy-Utils dependency updated to 0.25.0


0.10.3 (2014-02-27)
-------------------

* Fixed version next / previous handling

* SQLAlchemy dependency updated to 0.9.3

* Fixed column onupdate to history table reflection (issue #47)


0.10.2 (2014-02-10)
-------------------

* Fixed MySQL support (issue #36)

* Added SQLite and MySQL to testing matrix


0.10.1 (2013-10-18)
-------------------

* Added vacuum function


0.10.0 (2013-10-09)
-------------------

* Validity versioning strategy

* Changeset supports custom transaction column names

* Reify -> Revert

* Fixed revert to support class level column exclusion


0.9.0 (2013-09-12)
------------------

* Ability to track property modifications

* New configuration options: track_property_modifications and
  modified_flag_suffix


0.8.7 (2013-09-04)
------------------

* Only autoincremented columns marked as autoincrement=False for
  history tables. This enables alembic migrations to generate without
  annoying explicit autoincrement=False args.


0.8.6 (2013-08-21)
------------------

* Custom database schema support added


0.8.5 (2013-08-01)
------------------

* TSVectorType columns not versioned by default (in order to avoid
  massive version histories)


0.8.4 (2013-07-31)
------------------

* Full MySQL and SQLite support added


0.8.3 (2013-07-29)
------------------

* Fixed UnitOfWork changed entities handling (now checks only for
  versioned attributes not all object attributes)

* Fixed UnitOfWork TransactionMeta object creation (now checks if
  actual modifications were made)


0.8.2 (2013-07-26)
------------------

* Fixed MySQL history table primary key generation
  (autoincrement=False now forced for transaction_id column)


0.8.1 (2013-07-25)
------------------

* Added support for SQLAlchemy-i18n


0.8.0 (2013-07-25)
------------------

* Added database independent transaction meta parameter handling
  (formerly supported postgres only)


0.7.13 (2013-07-24)
-------------------

* Smarter is_modified handling for UnitOfWork (now understands
  excluded properties)


0.7.12 (2013-07-23)
-------------------

* Fixed FlaskVersioningManager schematics when working outside of
  request context (again)

* Added possibility to use custom UnitOfWork class


0.7.11 (2013-07-23)
-------------------

* Fixed FlaskVersioningManager schematics when working outside of
  request context


0.7.10 (2013-07-23)
-------------------

* Fixed is_auto_assigned_date_column (again)

* Moved some core utility functions to SQLAlchemy-Utils


0.7.9 (2013-07-23)
------------------

* Fixed is_auto_assigned_date_column

* Inflection added to requirements


0.7.8 (2013-07-03)
------------------

* Removed Versioned base class (adding __versioned__ attribute and
  calling make_versioned() is sufficient for making declarative class
  versioned)


0.7.7 (2013-07-03)
------------------

* DateTime columns with defaults excluded by default from history
  classes

* Column inclusion added as option


0.7.6 (2013-07-03)
------------------

* Smarter changeset handling


0.7.5 (2013-07-03)
------------------

* Improved reify() speed


0.7.4 (2013-07-03)
------------------

* Fixed changeset when parent contains more columns than version
  class.


0.7.3 (2013-06-27)
------------------

* Transaction log and transaction changes records only created if
  actual net changes were made during transaction.


0.7.2 (2013-06-27)
------------------

* Removed last references for old revision versioning


0.7.1 (2013-06-27)
------------------

* Added is_versioned utility function

* Fixed before operation listeners


0.7.0 (2013-06-27)
------------------

* Version tables no longer have revision column

* Parent tables no longer need revision column

* Version tables primary key is now (parent table pks +
  transaction_id)


0.6.8 (2013-06-26)
------------------

* Make versioned join table inherited classes support multiple
  consecutive flushes per transaction


0.6.7 (2013-06-26)
------------------

* Fixed association versioning when using executemany


0.6.6 (2013-06-26)
------------------

* Improved transaction log changed_entities schematics


0.6.5 (2013-06-26)
------------------

* Added possibility to add lazy values in transaction context meta


0.6.4 (2013-06-25)
------------------

* Version tables no longer generated when versioning attribute of
  model set to False


0.6.3 (2013-06-25)
------------------

* Revision column not nullable in version classes


0.6.2 (2013-06-25)
------------------

* Fixed relationship building for non-versioned classes


0.6.1 (2013-06-25)
------------------

* Parent table primary keys remain not nullable in generated version
  table


0.6.0 (2013-06-25)
------------------

* Added database agnostic versioning (no need for PostgreSQL specific
  triggers anymore)

* Fixed version object relationships (never worked properly in
  previous versions)

* New configuration option versioning allows setting the versioning on
  and off per child class.

* Added column exclusion


0.5.1 (2013-06-20)
------------------

* Added improved context managing capabilities for transactions via
  VersioningManager.tx_context


0.5.0 (2013-06-20)
------------------

* Removed Versioned base class, versioned objects only need to have
  __versioned__ defined.

* Session versioning now part of make_versioned function

* Added meta parameter in TransactionLog

* TransactionChanges model for tracking changed entities in given
  transaction

* Added Flask extension


0.4.2 (2013-06-18)
------------------

* Alembic trigger syncing fixed for drop column and add column


0.4.1 (2013-06-18)
------------------

* Alembic trigger syncing fixed


0.4.0 (2013-06-18)
------------------

* Added support for multiple updates for same row within single
  transaction

* History tables have now own revision column


0.3.12 (2013-06-18)
-------------------

* Not null constraints removed from all reflected columns

* Fixed reify when parent has not null constraints

* Added support for reifying deletion


0.3.11 (2013-06-18)
-------------------

* Single table inheritance support added


0.3.10 (2013-06-18)
-------------------

* Generated operation_type column not nullable by default


0.3.9 (2013-06-18)
------------------

* Added drop_table trigger synchronization


0.3.8 (2013-06-18)
------------------

* Autoincrementation automatically removed from reflected primary keys


0.3.7 (2013-06-18)
------------------

* Added identifier quoting for all column names


0.3.6 (2013-06-18)
------------------

* Identifier quoting for create_trigger_sql


0.3.5 (2013-06-12)
------------------

* Added alembic operations proxy class


0.3.4 (2013-06-12)
------------------

* VersioningManager now added in __versioned__ dict of each versioned
  class


0.3.3 (2013-06-12)
------------------

* Creating TransactionLog now checks if it already exists.


0.3.2 (2013-06-12)
------------------

* Added operation_type column to version tables.


0.3.1 (2013-06-12)
------------------

* Versioned mixin no longer holds lists of pending objects

* Added VersioningManager for more customizable versioning syntax


0.3.0 (2013-06-10)
------------------

* Model changesets

* Fixed previous and next accessors

* Updates generate versions only if actual changes occur


0.2.1 (2013-06-10)
------------------

* Added sanity check in all_affected_entities


0.2.0 (2013-06-10)
------------------

* Added backref relations to TransactionLog

* Added all_affected_entities property to TransactionLog


0.1.9 (2013-06-10)
------------------

* Renamed internal attribute __pending__ to __pending_versioned__ in
  order to avoid variable naming collisions.


0.1.8 (2013-06-10)
------------------

* Better checking of model table name in scenarios where model does
  not have __tablename__ defined.


0.1.7 (2013-06-07)
------------------

* Added make_versioned for more robust declaration of versioned
  mappers


0.1.6 (2013-06-07)
------------------

* Added PostgreSQLAdapter class


0.1.5 (2013-06-07)
------------------

* Made trigger procedures table specific to allow more fine-grained
  control.


0.1.4 (2013-06-06)
------------------

* Added column order inspection.


0.1.3 (2013-06-06)
------------------

* Removed foreign key dependency from version table and transaction
  table


0.1.2 (2013-06-06)
------------------

* Fixed packaging


0.1.1 (2013-06-06)
------------------

* Initial support for join table inheritance


0.1.0 (2013-06-05)
------------------

* Initial release
