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()