def init_versioning(self, app, database, versioning_manager=None): """Initialize the versioning support using SQLAlchemy-Continuum.""" try: pkg_resources.get_distribution('sqlalchemy_continuum') except pkg_resources.DistributionNotFound: # pragma: no cover default_versioning = False else: default_versioning = True app.config.setdefault('DB_VERSIONING', default_versioning) if not app.config['DB_VERSIONING']: return if not default_versioning: # pragma: no cover raise RuntimeError( 'Please install extra versioning support first by running ' 'pip install invenio-db[versioning].' ) # Now we can import SQLAlchemy-Continuum. from sqlalchemy_continuum import make_versioned from sqlalchemy_continuum import versioning_manager as default_vm from sqlalchemy_continuum.plugins import FlaskPlugin # Try to guess user model class: if 'DB_VERSIONING_USER_MODEL' not in app.config: # pragma: no cover try: pkg_resources.get_distribution('invenio_accounts') except pkg_resources.DistributionNotFound: user_cls = None else: user_cls = 'User' else: user_cls = app.config.get('DB_VERSIONING_USER_MODEL') plugins = [FlaskPlugin()] if user_cls else [] extra_plugins = app.config.get('DB_EXTRA_PLUGINS', []) plugins.extend(import_string(obj)() for obj in extra_plugins) # Call make_versioned() before your models are defined. self.versioning_manager = versioning_manager or default_vm make_versioned( user_cls=user_cls, manager=self.versioning_manager, plugins=plugins, ) # Register models that have been loaded beforehand. builder = self.versioning_manager.builder for tbl in database.metadata.tables.values(): builder.instrument_versioned_classes( database.mapper, get_class_by_table(database.Model, tbl) )
def init_versioning(self, app, database, versioning_manager=None): """Initialize the versioning support using SQLAlchemy-Continuum.""" try: pkg_resources.get_distribution('sqlalchemy_continuum') except pkg_resources.DistributionNotFound: # pragma: no cover default_versioning = False else: default_versioning = True app.config.setdefault('DB_VERSIONING', default_versioning) if not app.config['DB_VERSIONING']: return if not default_versioning: # pragma: no cover raise RuntimeError( 'Please install extra versioning support first by running ' 'pip install invenio-db[versioning].' ) # Now we can import SQLAlchemy-Continuum. from sqlalchemy_continuum import make_versioned from sqlalchemy_continuum import versioning_manager as default_vm from sqlalchemy_continuum.plugins import FlaskPlugin # Try to guess user model class: if 'DB_VERSIONING_USER_MODEL' not in app.config: # pragma: no cover try: pkg_resources.get_distribution('invenio_accounts') except pkg_resources.DistributionNotFound: user_cls = None else: user_cls = 'User' else: user_cls = app.config.get('DB_VERSIONING_USER_MODEL') plugins = [FlaskPlugin()] if user_cls else [] # Call make_versioned() before your models are defined. self.versioning_manager = versioning_manager or default_vm make_versioned( user_cls=user_cls, manager=self.versioning_manager, plugins=plugins, ) # Register models that have been loaded beforehand. builder = self.versioning_manager.builder for tbl in database.metadata.tables.values(): builder.instrument_versioned_classes( database.mapper, get_class_by_table(database.Model, tbl) )
def init_versioning(self, app, database, versioning_manager=None): """Initialize the versioning support using SQLAlchemy-Continuum.""" try: importlib_metadata.version("sqlalchemy_continuum") except importlib_metadata.PackageNotFoundError: # pragma: no cover default_versioning = False else: default_versioning = True app.config.setdefault("DB_VERSIONING", default_versioning) if not app.config["DB_VERSIONING"]: return if not default_versioning: # pragma: no cover raise RuntimeError( "Please install extra versioning support first by running " "pip install invenio-db[versioning].") # Now we can import SQLAlchemy-Continuum. from sqlalchemy_continuum import make_versioned from sqlalchemy_continuum import versioning_manager as default_vm from sqlalchemy_continuum.plugins import FlaskPlugin # Try to guess user model class: if "DB_VERSIONING_USER_MODEL" not in app.config: # pragma: no cover try: importlib_metadata.version("invenio_accounts") except importlib_metadata.PackageNotFoundError: user_cls = None else: user_cls = "User" else: user_cls = app.config.get("DB_VERSIONING_USER_MODEL") plugins = [FlaskPlugin()] if user_cls else [] # Call make_versioned() before your models are defined. self.versioning_manager = versioning_manager or default_vm make_versioned( user_cls=user_cls, manager=self.versioning_manager, plugins=plugins, ) # Register models that have been loaded beforehand. builder = self.versioning_manager.builder for tbl in database.metadata.tables.values(): builder.instrument_versioned_classes( database.mapper, get_class_by_table(database.Model, tbl))
def test_volume_dependent_models_list(self): """Make sure the volume dependent tables list is accurate.""" # Addresses LP Bug #1542169 volume_declarative_base = saf.get_declarative_base(models.Volume) volume_fks = saf.get_referencing_foreign_keys(models.Volume) dependent_tables = [] for table, fks in saf.group_foreign_keys(volume_fks): dependent_tables.append(table) found_dependent_models = [] for table in dependent_tables: found_dependent_models.append( saf.get_class_by_table(volume_declarative_base, table)) self.assertEqual(len(found_dependent_models), len(db_api.VOLUME_DEPENDENT_MODELS)) for model in found_dependent_models: self.assertIn(model, db_api.VOLUME_DEPENDENT_MODELS)
def get_sqlalchemy_mapping(self, registry, namespace, fieldname, properties): """ Create the relationship :param registry: the registry which load the relationship :param namespace: the name space of the model :param fieldname: fieldname of the relationship :param properties: the properties known :rtype: Many2One relationship """ self.model.check_model(registry) self.local_model = ModelRepr(namespace) local_columns, remote_columns = self.get_local_and_remote_columns( registry) join_table = self.get_join_table(registry, namespace, fieldname) has_join_table, schema = self.has_join_table_for_schema( registry, namespace, properties, join_table) if not has_join_table: modelname = ''.join(x.capitalize() for x in join_table.split('_')) remote_columns, remote_fk, secondaryjoin = self.get_m2m_columns( registry, remote_columns, self.m2m_remote_columns, modelname, suffix="right" if namespace == self.model.model_name else "" ) local_columns, local_fk, primaryjoin = self.get_m2m_columns( registry, local_columns, self.m2m_local_columns, modelname, suffix="left" if namespace == self.model.model_name else "" ) Node = Table(join_table, registry.declarativebase.metadata, *( local_columns + remote_columns + [local_fk, remote_fk]), schema=schema) if namespace == self.model.model_name: type(modelname, (registry.declarativebase,), { '__table__': Node }) self.kwargs['primaryjoin'] = primaryjoin self.kwargs['secondaryjoin'] = secondaryjoin elif namespace == self.model.model_name or self.compute_join: table = registry.declarativebase.metadata.tables[ '%s.%s' % (schema, join_table) if schema else join_table] cls = get_class_by_table(registry.declarativebase, table) modelname = ModelRepr(cls.__registry_name__).modelname(registry) if ( self.m2m_local_columns is None and self.m2m_remote_columns is None ): raise FieldException( "No 'm2m_local_columns' and 'm2m_remote_columns' " "attribute filled for many2many " "%r on model %r" % (fieldname, namespace)) elif self.m2m_local_columns is None: raise FieldException( "No 'm2m_local_columns' attribute filled for many2many " "%r on model %r" % (fieldname, namespace)) elif self.m2m_remote_columns is None: raise FieldException( "No 'm2m_remote_columns' attribute filled for many2many" " %r on model %r" % (fieldname, namespace)) remote_columns, remote_fk, secondaryjoin = self.get_m2m_columns( registry, remote_columns, self.m2m_remote_columns, modelname, suffix="right" if namespace == self.model.model_name else "" ) local_columns, local_fk, primaryjoin = self.get_m2m_columns( registry, local_columns, self.m2m_local_columns, modelname, suffix="left" if namespace == self.model.model_name else "" ) self.kwargs['primaryjoin'] = primaryjoin self.kwargs['secondaryjoin'] = secondaryjoin self.kwargs['secondary'] = ( '%s.%s' % (schema, join_table) if schema else join_table) # definition of expiration if self.kwargs.get('backref'): self.init_expire_attributes(registry, namespace, fieldname) backref = self.kwargs['backref'] if isinstance(backref, (tuple, list)): backref = backref[0] registry.expire_attributes[namespace][fieldname].add( ('x2m', fieldname, backref)) model_name = self.model.model_name self.init_expire_attributes(registry, model_name, backref) registry.expire_attributes[model_name][backref].add( ('x2m', backref, fieldname)) return super(Many2Many, self).get_sqlalchemy_mapping( registry, namespace, fieldname, properties)
def get_sqlalchemy_mapping(self, registry, namespace, fieldname, properties): """ Create the relationship :param registry: the registry which load the relationship :param namespace: the name space of the model :param fieldname: fieldname of the relationship :param properties: the properties known :rtype: Many2One relationship """ self.model.check_model(registry) self.local_model = ModelRepr(namespace) local_columns, remote_columns = self.get_local_and_remote_columns( registry) join_table = self.get_join_table(registry, namespace, fieldname) if join_table not in registry.declarativebase.metadata.tables: modelname = ''.join(x.capitalize() for x in join_table.split('_')) remote_columns, remote_fk, secondaryjoin = self.get_m2m_columns( registry, remote_columns, self.m2m_remote_columns, modelname, suffix="right" if namespace == self.model.model_name else "" ) local_columns, local_fk, primaryjoin = self.get_m2m_columns( registry, local_columns, self.m2m_local_columns, modelname, suffix="left" if namespace == self.model.model_name else "" ) Node = Table(join_table, registry.declarativebase.metadata, *( local_columns + remote_columns + [local_fk, remote_fk])) if namespace == self.model.model_name: type(modelname, (registry.declarativebase,), { '__table__': Node }) self.kwargs['primaryjoin'] = primaryjoin self.kwargs['secondaryjoin'] = secondaryjoin elif namespace == self.model.model_name or self.compute_join: table = registry.declarativebase.metadata.tables[join_table] cls = get_class_by_table(registry.declarativebase, table) modelname = ModelRepr(cls.__registry_name__).modelname(registry) if ( self.m2m_local_columns is None and self.m2m_remote_columns is None ): raise FieldException( "No 'm2m_local_columns' and 'm2m_remote_columns' " "attribute filled for many2many " "%r on model %r" % (fieldname, namespace)) elif self.m2m_local_columns is None: raise FieldException( "No 'm2m_local_columns' attribute filled for many2many " "%r on model %r" % (fieldname, namespace)) elif self.m2m_remote_columns is None: raise FieldException( "No 'm2m_remote_columns' attribute filled for many2many" " %r on model %r" % (fieldname, namespace)) remote_columns, remote_fk, secondaryjoin = self.get_m2m_columns( registry, remote_columns, self.m2m_remote_columns, modelname, suffix="right" if namespace == self.model.model_name else "" ) local_columns, local_fk, primaryjoin = self.get_m2m_columns( registry, local_columns, self.m2m_local_columns, modelname, suffix="left" if namespace == self.model.model_name else "" ) self.kwargs['primaryjoin'] = primaryjoin self.kwargs['secondaryjoin'] = secondaryjoin self.kwargs['secondary'] = join_table # definition of expiration if self.kwargs.get('backref'): self.init_expire_attributes(registry, namespace, fieldname) backref = self.kwargs['backref'] if isinstance(backref, (tuple, list)): backref = backref[0] registry.expire_attributes[namespace][fieldname].add( ('x2m', fieldname, backref)) model_name = self.model.model_name self.init_expire_attributes(registry, model_name, backref) registry.expire_attributes[model_name][backref].add( ('x2m', backref, fieldname)) return super(Many2Many, self).get_sqlalchemy_mapping( registry, namespace, fieldname, properties)
def item(self): return get_class_by_table(db.Model, db.Model.metadata.tables[self.item_table]).query.filter_by(id=self.item_id).first()
def make_pair(v): c = get_class_by_table(base, v[1]) return (c.__name__, c)