# Path: sqlalchemy_continuum/utils.py
# def end_tx_column_name(obj):
#     return option(obj, 'end_transaction_column_name')
# 
# def version_class(model):
#     """
#     Return the version class for given SQLAlchemy declarative model class.
# 
#     ::
# 
#         version_class(Article)  # ArticleVersion class
# 
# 
#     :param model: SQLAlchemy declarative model class
# 
#     .. seealso:: :func:`parent_class`
#     """
#     manager = get_versioning_manager(model)
#     try:
#         return manager.version_class_map[model]
#     except KeyError:
#         return model
# 
# def is_session_modified(session):
#     """
#     Return whether or not any of the versioned objects in given session have
#     been either modified or deleted.
# 
#     :param session: SQLAlchemy session object
# 
#     .. seealso:: :func:`is_versioned`
#     .. seealso:: :func:`versioned_objects`
#     """
#     return any(
#         is_modified_or_deleted(obj) for obj in versioned_objects(session)
#     )
# 
# def tx_column_name(obj):
#     return option(obj, 'transaction_column_name')
# 
# def versioned_column_properties(obj_or_class):
#     """
#     Return all versioned column properties for given versioned SQLAlchemy
#     declarative model object.
# 
#     :param obj: SQLAlchemy declarative model object
#     """
#     manager = get_versioning_manager(obj_or_class)
# 
#     cls = obj_or_class if isclass(obj_or_class) else obj_or_class.__class__
# 
#     mapper = sa.inspect(cls)
#     for key, column in mapper.columns.items():
#         # Ignores non table columns
#         if not is_table_column(column):
#             continue
# 
#         if not manager.is_excluded_property(obj_or_class, key):
#             yield getattr(mapper.attrs, key)


from copy import copy
from sqlalchemy_utils import get_primary_keys, identity
from .operation import Operations
from .utils import (
    end_tx_column_name,
    version_class,
    is_session_modified,
    tx_column_name,
    versioned_column_properties
)
import sqlalchemy as sa

        .. seealso:: :func:`version_validity_subquery`
        """
        session = sa.orm.object_session(version_obj)

        for class_ in version_obj.__class__.__mro__:
            if class_ in self.manager.parent_class_map:

                subquery = self.version_validity_subquery(
                    parent,
                    version_obj,
                    alias=sa.orm.aliased(class_.__table__)
                )
                try:
                    subquery = subquery.scalar_subquery()
                except AttributeError:  # SQLAlchemy < 1.4
                    subquery = subquery.as_scalar()

                query = (
                    session.query(class_.__table__)
                    .filter(
                        sa.and_(
                            getattr(
                                class_,
                                tx_column_name(version_obj)
                            ) == subquery,
                            *[
                                getattr(version_obj, pk) ==
                                getattr(class_.__table__.c, pk)
                                for pk in get_primary_keys(class_)

# Path: sqlalchemy_continuum/utils.py
# def end_tx_column_name(obj):
#     return option(obj, 'end_transaction_column_name')
# 
# def version_class(model):
#     """
#     Return the version class for given SQLAlchemy declarative model class.
# 
#     ::
# 
#         version_class(Article)  # ArticleVersion class
# 
# 
#     :param model: SQLAlchemy declarative model class
# 
#     .. seealso:: :func:`parent_class`
#     """
#     manager = get_versioning_manager(model)
#     try:
#         return manager.version_class_map[model]
#     except KeyError:
#         return model
# 
# def is_session_modified(session):
#     """
#     Return whether or not any of the versioned objects in given session have
#     been either modified or deleted.
# 
#     :param session: SQLAlchemy session object
# 
#     .. seealso:: :func:`is_versioned`
#     .. seealso:: :func:`versioned_objects`
#     """
#     return any(
#         is_modified_or_deleted(obj) for obj in versioned_objects(session)
#     )
# 
# def tx_column_name(obj):
#     return option(obj, 'transaction_column_name')
# 
# def versioned_column_properties(obj_or_class):
#     """
#     Return all versioned column properties for given versioned SQLAlchemy
#     declarative model object.
# 
#     :param obj: SQLAlchemy declarative model object
#     """
#     manager = get_versioning_manager(obj_or_class)
# 
#     cls = obj_or_class if isclass(obj_or_class) else obj_or_class.__class__
# 
#     mapper = sa.inspect(cls)
#     for key, column in mapper.columns.items():
#         # Ignores non table columns
#         if not is_table_column(column):
#             continue
# 
#         if not manager.is_excluded_property(obj_or_class, key):
#             yield getattr(mapper.attrs, key)


# Path: sqlalchemy_continuum/unit_of_work.py
from copy import copy
from sqlalchemy_utils import get_primary_keys, identity
from .operation import Operations
from .utils import (
    end_tx_column_name,
    version_class,
    is_session_modified,
    tx_column_name,
    versioned_column_properties
)
import sqlalchemy as sa


        .. seealso:: :func:`version_validity_subquery`
        """
        session = sa.orm.object_session(version_obj)

        for class_ in version_obj.__class__.__mro__:
            if class_ in self.manager.parent_class_map:

                subquery = self.version_validity_subquery(
                    parent,
                    version_obj,
                    alias=sa.orm.aliased(class_.__table__)
                )
                try:
                    subquery = subquery.scalar_subquery()
                except AttributeError:  # SQLAlchemy < 1.4
                    subquery = subquery.as_scalar()

                query = (
                    session.query(class_.__table__)
                    .filter(
                        sa.and_(
                            getattr(
                                class_,
                                tx_column_name(version_obj)
                            ) == subquery,
                            *[
                                getattr(version_obj, pk) ==
                                getattr(class_.__table__.c, pk)
                                for pk in get_primary_keys(class_)

                                if pk != tx_column_name(class_)