Reverting changes

One of the major benefits of SQLAlchemy-History is its ability to revert changes.

Revert update

>>> article = Article(name=u'New article', content=u'Some content')
>>> session.add(article)
>>> session.commit(article)
>>> version = article.versions[0]
>>> article.name = u'Updated article'
>>> session.commit()
>>> version.revert()
>>> session.commit()
>>> article.name
'New article'

Revert delete

>>> article = Article(name=u'New article', content=u'Some content')
>>> session.add(article)
>>> session.commit(article)
>>> version = article.versions[0]
>>> session.delete(article)
>>> session.commit()
>>> version.revert()
>>> session.commit() # article lives again!
>>> session.query(Article).first()

Revert relationships

Sometimes you may have cases where you want to revert an object as well as some of its relation to certain state. Consider the following model definition:

>>> class Article(Base):
...     __tablename__ = 'article'
...     __versioned__ = {}
...     id = sa.Column(sa.Integer, autoincrement=True, primary_key=True)
...     name = sa.Column(sa.Unicode(255))
>>> class Tag(Base):
...     __tablename__ = 'tag'
...     __versioned__ = {}
...     id = sa.Column(sa.Integer, autoincrement=True, primary_key=True)
...     name = sa.Column(sa.Unicode(255))
...     article_id = sa.Column(sa.Integer, sa.ForeignKey(Article.id))
...     article = sa.orm.relationship(Article, backref='tags')

Now lets say some user first adds an article with couple of tags:

>>> article = Article(
...     name=u'Some article',
...     tags=[Tag(u'Good'), Tag(u'Interesting')]
... )
>>> session.add(article)
>>> session.commit()

Then lets say another user deletes one of the tags:

>>> tag = session.query(Tag).filter_by(name=u'Interesting')
>>> session.delete(tag)
>>> session.commit()

Now the first user wants to set the article back to its original state. It can be achieved as follows (notice how we use the relations parameter):

>>> article = session.query(Article).get(1)
>>> article.versions[0].revert(relations=['tags'])
>>> session.commit()