Skip to content
Snippets Groups Projects
Commit 6be60647 authored by Benjamin Bertrand's avatar Benjamin Bertrand
Browse files

Add items versioning with SQLAlchemy-Continuum

parent fe73933d
No related branches found
No related tags found
No related merge requests found
......@@ -11,16 +11,20 @@ This module implements the models used in the app.
"""
import re
import qrcode
import sqlalchemy as sa
from sqlalchemy.orm import validates
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy_continuum import make_versioned
from citext import CIText
from flask import current_app
from flask_login import UserMixin
from .extensions import db, login_manager, ldap_manager, jwt
from .plugins import FlaskUserPlugin
from . import utils
ICS_ID_RE = re.compile('[A-Z]{3}[0-9]{3}')
make_versioned(plugins=[FlaskUserPlugin()])
@login_manager.user_loader
......@@ -183,6 +187,10 @@ class Status(QRCodeMixin, db.Model):
class Item(db.Model):
__versioned__ = {
'exclude': ['_created']
}
id = db.Column(db.Integer, primary_key=True)
_created = db.Column(db.DateTime, default=db.func.now())
_updated = db.Column(db.DateTime, default=db.func.now(), onupdate=db.func.now())
......@@ -231,3 +239,8 @@ class Item(db.Model):
'updated': utils.format_field(self._updated),
'created': utils.format_field(self._created),
}
# call configure_mappers after defining all the models
# required by sqlalchemy_continuum
sa.orm.configure_mappers()
# -*- coding: utf-8 -*-
"""
app.plugins
~~~~~~~~~~~
This module implements SQLAlchemy-Continuum plugins.
FlaskUserPlugin offers way of integrating Flask framework with
SQLAlchemy-Continuum. FlaskUser-Plugin adds a `user_id` column for Transaction model.
This plugin is based on the official FlaskPlugin with the following modifications:
- no remote_addr column
- the user_id is taken from flask_jwt_extended (API) or flask_login (web UI)
The `user_id` column is automatically populated when the transaction object is created.
:copyright: original (c) 2012, Konsta Vesterinen
:copyright: modified (c) 2017 European Spallation Source ERIC
:license: BSD 2-Clause, see LICENSE for more details.
"""
from flask.globals import _app_ctx_stack, _request_ctx_stack
from sqlalchemy_continuum.plugins import Plugin
from flask_login import current_user
from flask_jwt_extended import get_current_user
def fetch_current_user_id():
# Return None if we are outside of request context.
if _app_ctx_stack.top is None or _request_ctx_stack.top is None:
return None
# Try to get the user from both flask_jwt_extended and flask_login
user = get_current_user() or current_user
try:
return user.id
except AttributeError:
return None
class FlaskUserPlugin(Plugin):
def __init__(
self,
current_user_id_factory=None,
):
self.current_user_id_factory = (
fetch_current_user_id if current_user_id_factory is None
else current_user_id_factory
)
def transaction_args(self, uow, session):
return {
'user_id': self.current_user_id_factory(),
}
......@@ -60,4 +60,6 @@ dependencies:
- pyasn1==0.2.3
- pyjwt==1.4.2
- sqlalchemy-citext==1.3.post0
- sqlalchemy-continuum==1.3.1
- sqlalchemy-utils==0.32.14
- visitor==0.1.3
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment