Add undo/redo functionality for Flask applications that use SQLAlchemy.
Flask-UndoRedo is a Flask extension that uses the SQLAlchemy event API to record inserts, updates, and deletes in order to later undo or redo them.
Installation via pip:
pip install Flask-UndoRedo
The following is an example of integrating Flask-UndoRedo into application initialization.
from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_undoredo import UndoRedo db = SQLAlchemy() undo_redo = UndoRedo() app = Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///:memory:" app.config["UNDO_REDO_DATABASE_URI"] = "sqlite:///:memory:" db.init_app(app) undo_redo.init_app(app)
The string value associated with the
UNDO_REDO_DATABASE_URI configuration key is used to connect to the desired database. The value is expected to be in the same format as that provided to SQLAlchemy.
Flask-UndoRedo will create an
undo_action and a
redo_action table in the public schema when the
init_app method is first called. The Flask-UndoRedo API provides
redo methods available on the
capture method returns a context manager. SQL queries executed within this context are captured and logged to the
db.session.flush() with undo_redo.capture(db.session, "document", document.id): Document.query.filter_by(name=name).delete()
capture method requires a session with which to execute its own queries, an object type, as well as an integer value to associate the capture session with. These values should be provided to the
redo methods in order to manipulate the correct history.
undo, redo = undo_redo.undo(db.session, "document", document.id) undo, redo = undo_redo.redo(db.session, "document", document.id)
Both methods return the count of available undo and redo actions as of when that call was completed. Calling either method will cause SQL statements that were generated and logged earlier during a capture session to be executed. Inserts will be issued to negate deletes, deletes to undo inserts, and inverse updates for earlier updates.
As of this writing, Flask-UndoRedo does not support all SQLAlchemy ORM queries. Please refer to the test cases as a guide to what statements have been proven to work.
Please read http://www.codetodd.com/undo-redo-for-flask-and-sqlalchemy/ for more discussion of limitations and implementation details.