mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-10 19:00:25 -04:00
40f8aadd58
- added READMEs to all examples in each __init__.py and added to sphinx documentation - added versioning example - removed vertical/vertical.py, the dictlikes are more straightforward
67 lines
2.1 KiB
Python
67 lines
2.1 KiB
Python
"""
|
|
Illustrates an extension which creates version tables for entities and stores records for each change. The same idea as Elixir's versioned extension, but more efficient (uses attribute API to get history) and handles class inheritance. The given extensions generate an anonymous "history" class which represents historical versions of the target object.
|
|
|
|
Usage is illustrated via a unit test module ``test_versioning.py``, which can be run via nose::
|
|
|
|
nosetests -w examples/versioning/
|
|
|
|
A fragment of example usage, using declarative::
|
|
|
|
from history_meta import VersionedMeta, VersionedListener
|
|
|
|
Base = declarative_base(metaclass=VersionedMeta, bind=engine)
|
|
Session = sessionmaker(extension=VersionedListener())
|
|
|
|
class SomeClass(Base):
|
|
__tablename__ = 'sometable'
|
|
|
|
id = Column(Integer, primary_key=True)
|
|
name = Column(String(50))
|
|
|
|
def __eq__(self, other):
|
|
assert type(other) is SomeClass and other.id == self.id
|
|
|
|
sess = Session()
|
|
sc = SomeClass(name='sc1')
|
|
sess.add(sc)
|
|
sess.commit()
|
|
|
|
sc.name = 'sc1modified'
|
|
sess.commit()
|
|
|
|
assert sc.version == 2
|
|
|
|
SomeClassHistory = SomeClass.__history_mapper__.class_
|
|
|
|
assert sess.query(SomeClassHistory).\\
|
|
filter(SomeClassHistory.version == 1).\\
|
|
all() \\
|
|
== [SomeClassHistory(version=1, name='sc1')]
|
|
|
|
To apply ``VersionedMeta`` to a subset of classes (probably more typical), the metaclass can be applied on a per-class basis::
|
|
|
|
from history_meta import VersionedMeta, VersionedListener
|
|
|
|
Base = declarative_base(bind=engine)
|
|
|
|
class SomeClass(Base):
|
|
__tablename__ = 'sometable'
|
|
|
|
# ...
|
|
|
|
class SomeVersionedClass(Base):
|
|
__metaclass__ = VersionedMeta
|
|
__tablename__ = 'someothertable'
|
|
|
|
# ...
|
|
|
|
The ``VersionedMeta`` is a declarative metaclass - to use the extension with plain mappers, the ``_history_mapper`` function can be applied::
|
|
|
|
from history_meta import _history_mapper
|
|
|
|
m = mapper(SomeClass, sometable)
|
|
_history_mapper(m)
|
|
|
|
SomeHistoryClass = SomeClass.__history_mapper__.class_
|
|
|
|
""" |