This approach uses part of sqlalchemy example history_meta code

adapted to recording inserts and updates.

This removes need to manually create history tables.

Our code still remains in control of when history records are
created.
This commit is contained in:
Adam Shimali
2016-04-14 15:09:59 +01:00
parent 16553af133
commit a6a18c1a6f
10 changed files with 442 additions and 54 deletions

48
app/dao/dao_utils.py Normal file
View File

@@ -0,0 +1,48 @@
import datetime
from functools import wraps
def create_history(obj):
history_mapper = obj.__history_mapper__
history_model = history_mapper.class_
history = history_model()
if obj.version:
obj.version += 1
else:
obj.version = 1
obj.created_at = datetime.datetime.now()
for prop in history_mapper.iterate_properties:
if obj.__mapper__.get_property(prop.key):
setattr(history, prop.key, getattr(obj, prop.key))
history.created_by_id = obj.created_by.id
return history
def transactional(func):
@wraps(func)
def commit_or_rollback(*args, **kwargs):
from flask import current_app
from app import db
try:
func(*args, **kwargs)
db.session.commit()
except Exception as e:
current_app.logger.error(e)
db.session.rollback()
raise
return commit_or_rollback
def versioned(func):
@wraps(func)
def record_version(*args, **kwargs):
import itertools
from app import db
from app.history_meta import versioned_objects
from app.dao.dao_utils import create_history
func(*args, **kwargs)
for obj in versioned_objects(itertools.chain(db.session.new, db.session.dirty)):
history = create_history(obj)
db.session.add(history)
return record_version

View File

@@ -30,22 +30,7 @@ from app.clients import (
STATISTICS_REQUESTED
)
from functools import wraps
def transactional(func):
@wraps(func)
def commit_or_rollback(*args, **kwargs):
from flask import current_app
from app import db
try:
func(*args, **kwargs)
db.session.commit()
except Exception as e:
current_app.logger.error(e)
db.session.rollback()
raise
return commit_or_rollback
from app.dao.dao_utils import transactional
def get_character_count_of_content(content, encoding='utf-8'):

View File

@@ -1,7 +1,14 @@
import uuid
from app import db
from app.models import Service
from sqlalchemy import asc
from app.dao.dao_utils import (
transactional,
versioned
)
def dao_fetch_all_services():
return Service.query.order_by(asc(Service.created_at)).all()
@@ -19,22 +26,20 @@ def dao_fetch_service_by_id_and_user(service_id, user_id):
return Service.query.filter(Service.users.any(id=user_id)).filter_by(id=service_id).one()
@transactional
@versioned
def dao_create_service(service, user):
try:
from app.dao.permissions_dao import permission_dao
service.users.append(user)
permission_dao.add_default_service_permissions_for_user(user, service)
db.session.add(service)
except Exception as e:
db.session.rollback()
raise e
else:
db.session.commit()
from app.dao.permissions_dao import permission_dao
service.users.append(user)
permission_dao.add_default_service_permissions_for_user(user, service)
service.id = uuid.uuid4() # must be set now so version history model can use same id
db.session.add(service)
@transactional
@versioned
def dao_update_service(service):
db.session.add(service)
db.session.commit()
def dao_add_user_to_service(service, user, permissions=[]):