Skip to content

Commit

Permalink
server: Use SQLAlchemy-Continuum for logging changes - #65
Browse files Browse the repository at this point in the history
  • Loading branch information
andras-tim committed Jan 7, 2016
1 parent 40ef6e6 commit 0a0ecce
Show file tree
Hide file tree
Showing 6 changed files with 303 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased][unreleased]
### Added
- Configurable log and message format
- Start logging changes (without api export and WebUI currently) - issue #128

### Changed
- Replaced database migration framework - issue #115
Expand Down
33 changes: 33 additions & 0 deletions server/app/models.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
from datetime import datetime
from sqlalchemy import orm

from app.server import db, bcrypt
from app.modules.view_helper_for_models import nested_fields


class User(db.Model):
__versioned__ = {
'exclude': ('password_hash', )
}

id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(30), nullable=False, unique=True, index=True)
password_hash = db.Column(db.String(80), nullable=False)
Expand Down Expand Up @@ -42,6 +47,8 @@ def get_id(self) -> str:

@nested_fields(user=User)
class UserConfig(db.Model):
__versioned__ = {}

id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
name = db.Column(db.String(40), index=True, nullable=False)
Expand All @@ -58,6 +65,8 @@ def __repr__(self)-> str:


class Vendor(db.Model):
__versioned__ = {}

id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(60), nullable=False, unique=True)

Expand All @@ -68,6 +77,8 @@ def __repr__(self)-> str:


class Unit(db.Model):
__versioned__ = {}

id = db.Column(db.Integer, primary_key=True)
unit = db.Column(db.String(20), nullable=False, unique=True)

Expand All @@ -76,6 +87,8 @@ def __repr__(self)-> str:


class Customer(db.Model):
__versioned__ = {}

id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(60), nullable=False, unique=True)

Expand All @@ -85,6 +98,8 @@ def __repr__(self)-> str:

@nested_fields(vendor=Vendor, unit=Unit)
class Item(db.Model):
__versioned__ = {}

id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(60), nullable=False, unique=True)
vendor_id = db.Column(db.Integer, db.ForeignKey('vendor.id'), nullable=False)
Expand All @@ -104,6 +119,8 @@ def __repr__(self)-> str:

@nested_fields(item=Item)
class Barcode(db.Model):
__versioned__ = {}

id = db.Column(db.Integer, primary_key=True)
barcode = db.Column(db.String(15), nullable=False, unique=True, index=True)
quantity = db.Column(db.Float, nullable=False, default=1.0)
Expand All @@ -120,6 +137,8 @@ def __repr__(self)-> str:

@nested_fields(customer=Customer, outbound_close_user=User, returned_close_user=User)
class Work(db.Model):
__versioned__ = {}

id = db.Column(db.Integer, primary_key=True)
customer_id = db.Column(db.Integer, db.ForeignKey('customer.id'), nullable=False)
comment = db.Column(db.Text)
Expand Down Expand Up @@ -162,6 +181,8 @@ def close_returned_items(self, user: User):

@nested_fields(work=Work, item=Item)
class WorkItem(db.Model):
__versioned__ = {}

id = db.Column(db.Integer, primary_key=True)
work_id = db.Column(db.Integer, db.ForeignKey('work.id'), nullable=False)
item_id = db.Column(db.Integer, db.ForeignKey('item.id'), nullable=False)
Expand All @@ -180,6 +201,8 @@ def __repr__(self)-> str:


class Acquisition(db.Model):
__versioned__ = {}

id = db.Column(db.Integer, primary_key=True)
timestamp = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
comment = db.Column(db.Text)
Expand All @@ -192,6 +215,8 @@ def __repr__(self)-> str:

@nested_fields(acquisition=Acquisition, item=Item)
class AcquisitionItem(db.Model):
__versioned__ = {}

id = db.Column(db.Integer, primary_key=True)
acquisition_id = db.Column(db.Integer, db.ForeignKey('acquisition.id'), nullable=False)
item_id = db.Column(db.Integer, db.ForeignKey('item.id'), nullable=False)
Expand All @@ -209,6 +234,8 @@ def __repr__(self)-> str:


class Stocktaking(db.Model):
__versioned__ = {}

id = db.Column(db.Integer, primary_key=True)
timestamp = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
comment = db.Column(db.Text)
Expand Down Expand Up @@ -236,6 +263,8 @@ def close_items(self, user: User):

@nested_fields(stocktaking=Stocktaking, item=Item)
class StocktakingItem(db.Model):
__versioned__ = {}

id = db.Column(db.Integer, primary_key=True)
stocktaking_id = db.Column(db.Integer, db.ForeignKey('stocktaking.id'), nullable=False)
item_id = db.Column(db.Integer, db.ForeignKey('item.id'), nullable=False)
Expand All @@ -250,3 +279,7 @@ class StocktakingItem(db.Model):

def __repr__(self)-> str:
return '{!s} [{!r}]'.format(self.id, self.item)


# Setup SQLAlchemy-Continuum tables and hooks
orm.configure_mappers()
2 changes: 1 addition & 1 deletion server/app/modules/view_helper_for_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ def __initial_enumerate_nested_fields(self, model: db.Model):
if self.__nested_fields:
return

relationships = inspect(model.__class__).relationships
relationships = [rel for rel in inspect(model.__class__).relationships if rel.key != 'versions']
for relationship in relationships:
nested_field_name = relationship.key
for local_field, remote_field in relationship.local_remote_pairs:
Expand Down
4 changes: 4 additions & 0 deletions server/app/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from flask.ext.login import LoginManager
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.bcrypt import Bcrypt
from sqlalchemy_continuum import make_versioned, plugins

from app import test_mode, doc_mode, log, static
from app.config import get_config, check_warnings_in_config
Expand Down Expand Up @@ -38,6 +39,9 @@
# flask-bcrypt
bcrypt = Bcrypt(app)

# SQLAlchemy-Continuum
make_versioned(plugins=[plugins.FlaskPlugin()])

# Init views (must be after common resources)
import app.views as views
views.initialize_endpoints(config, api)
Expand Down
Loading

0 comments on commit 0a0ecce

Please sign in to comment.