Flask extension#
Flask extension provides means for easy integration with PostgreSQL-Audit, Flask-Login and Flask-SQLAlchemy. It provides all the goodies that SQLAlchemy integration provides along with:
By default, the Flask extensions tries to get the current user from Flask-Login and assigns the id of this object as the
actor_id
of all activities in given transaction. It also assigns the current user’s IP address to all present activities.Easy overriding of current activity values using
activity_values
context manager
from postgresql_audit.flask import versioning_manager
from my_app.extensions import db
versioning_manager.init(db.Model)
class Article(db.Model):
__tablename__ = 'article'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
article = Article(name='Some article')
db.session.add(article)
db.session.commit()
Overriding activity values#
In some situations you may want to override the current activity values. One
scenario is where you want to track the changes to associated objects and mark
those changes with the target_id
property of the Activity
model.
For example, consider the following model structure with Article
and
Tag
. Let’s say we want to show the changelog of an article that contains all
changes to this article and its tags:
from postgresql_audit.flask import versioning_manager
from my_app.extensions import db
versioning_manager.init(db.Model)
class Article(db.Model):
__tablename__ = 'article'
__versioned__ = {}
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
class Tag(db.Model):
__tablename__ = 'tag'
__versioned__ = {}
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
article_id = db.Column(
db.Integer,
db.ForeignKey(Article.id, ondelete='CASCADE')
)
article = db.relationship(Article, backref='tags')
When tracking the changes to article, we don’t need any changes:
article = Article(name='Some article')
db.session.add(article)
db.session.commit()
When adding tags, we need to make the generated activities use the article id as
the target_id
so that we can track them later on:
from postgresql_audit.flask import activity_values
with activity_values(target_id=str(article.id)):
article.tags = [Tag(name='Some tag')]
db.session.commit()
Now, we can find all activities for an article with the following query:
Activity = versioning_manager.activity_cls
activities = Activity.query.filter(
db.or_(
db.and_(
Activity.target_id == str(article.id),
Activity.target_table_name == 'article'
),
db.and_(
db.or_(
Activity.row_data['id'] == article.id,
Activity.changed_fields['id'] == article.id
),
Activity.table_name == 'article'
)
)
).order_by(Activity.issued_at)
Recording IP address behind proxy#
By default PostgreSQL-Audit stores the client address as found in the request and does not attempt to make assumptions on server proxy configuration. Thus, in case the flask app runs after an http server (e.g nginx), and depending on configuration, flask may receive no IP. To overcome this, it is advised to follow flask documentation on proxy setups.