Skip to content

Commit

Permalink
global: avoid double versioned models registration
Browse files Browse the repository at this point in the history
* Checks for already registered models before building versioning
  models. (closes #96)
  • Loading branch information
slint committed Nov 21, 2017
1 parent 20c2751 commit eda4882
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
4 changes: 3 additions & 1 deletion invenio_db/ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

from .cli import db as db_cmd
from .shared import db
from .utils import versioning_models_registered


class InvenioDB(object):
Expand Down Expand Up @@ -95,7 +96,8 @@ def init_db(self, app, entry_point_group='invenio_db.models', **kwargs):
if app.config['DB_VERSIONING']:
manager = self.versioning_manager
if manager.pending_classes:
manager.builder.configure_versioned_classes()
if not versioning_models_registered(manager, database.Model):
manager.builder.configure_versioned_classes()
elif 'transaction' not in database.metadata.tables:
manager.declarative_base = database.Model
manager.create_transaction_model()
Expand Down
16 changes: 16 additions & 0 deletions invenio_db/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,19 @@ def drop_alembic_version_table():
alembic_version = _db.Table('alembic_version', _db.metadata,
autoload_with=_db.engine)
alembic_version.drop(bind=_db.engine)


def versioning_model_classname(manager, model):
"""Get the name of the versioned model class."""
if manager.options.get('use_module_name', True):
return '%s%sVersion' % (
model.__module__.title().replace('.', ''), model.__name__)
else:
return '%sVersion' % (model.__name__,)


def versioning_models_registered(manager, base):
"""Return True if all versioning models have been registered."""
declared_models = base._decl_class_registry.keys()
return all(versioning_model_classname(manager, c) in declared_models
for c in manager.pending_classes)
25 changes: 24 additions & 1 deletion tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@

import pytest
import sqlalchemy as sa
from mock import patch
from sqlalchemy_continuum import remove_versioning
from sqlalchemy_utils.types.encrypted import EncryptedType
from test_db import _mock_entry_points

from invenio_db import InvenioDB
from invenio_db.utils import rebuild_encrypted_properties
from invenio_db.utils import rebuild_encrypted_properties, \
versioning_model_classname, versioning_models_registered


def test_rebuild_encrypted_properties(db, app):
Expand Down Expand Up @@ -73,3 +77,22 @@ class Demo(db.Model):

with app.app_context():
db.drop_all()


def test_versioning_model_classname(db, app):
"""Test the versioning model utilities."""
class FooClass(db.Model):
__versioned__ = {}
pk = db.Column(db.Integer, primary_key=True)

app.config['DB_VERSIONING'] = True
idb = InvenioDB(app)
manager = idb.versioning_manager
manager.options['use_module_name'] = True
assert versioning_model_classname(manager, FooClass) == \
'Test_UtilsFooClassVersion'
manager.options['use_module_name'] = False
assert versioning_model_classname(
manager, FooClass) == 'FooClassVersion'
assert versioning_models_registered(manager, db.Model)
remove_versioning(manager=manager)

0 comments on commit eda4882

Please sign in to comment.