Source code for anyblok.model.table_and_mapper

# This file is a part of the AnyBlok project
#
#    Copyright (C) 2017 Jean-Sebastien SUZANNE <jssuzanne@anybox.fr>
#
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file,You can
# obtain one at http://mozilla.org/MPL/2.0/.
from .plugins import ModelPluginBase
from .exceptions import ModelException
from sqlalchemy import ForeignKeyConstraint, CheckConstraint
from sqlalchemy.ext.declarative import declared_attr


[docs]class TableMapperPlugin(ModelPluginBase):
[docs] def initialisation_tranformation_properties(self, properties, transformation_properties): """ Initialise the transform properties: hybrid_method :param new_type_properties: param to add in a new base if need """ properties['add_in_table_args'] = [] if 'table_args' not in transformation_properties: transformation_properties['table_args'] = False if 'mapper_args' not in transformation_properties: transformation_properties['mapper_args'] = False
[docs] def transform_base(self, namespace, base, transformation_properties, new_type_properties): """Test if define_table/mapper_args are in the base, and call them save the value in the properties if __table/mapper_args\_\_ are in the base then raise ModelException :param namespace: the namespace of the model :param base: One of the base of the model :param transformation_properties: the properties of the model :param new_type_properties: param to add in a new base if need """ if hasattr(base, '__table_args__'): raise ModelException( "'__table_args__' attribute is forbidden, on Model : %r (%r)." "Use the class method 'define_table_args' to define the value " "allow anyblok to fill his own '__table_args__' attribute" % ( namespace, base.__table_args__)) if hasattr(base, '__mapper_args__'): raise ModelException( "'__mapper_args__' attribute is forbidden, on Model : %r (%r)." "Use the class method 'define_mapper_args' to define the " "value allow anyblok to fill his own '__mapper_args__' " "attribute" % (namespace, base.__mapper_args__)) if hasattr(base, 'define_table_args'): transformation_properties['table_args'] = True if hasattr(base, 'define_mapper_args'): transformation_properties['mapper_args'] = True
[docs] def insert_in_bases(self, new_base, namespace, properties, transformation_properties): """ Create overwrite to define table and mapper args to define some options for SQLAlchemy :param new_base: the base to be put on front of all bases :param namespace: the namespace of the model :param properties: the properties declared in the model :param transformation_properties: the properties of the model """ table_args = tuple(properties['add_in_table_args']) if table_args: def define_table_args(cls_): if cls_.__registry_name__ == namespace: res = super(new_base, cls_).define_table_args() fks = [x.name for x in res if isinstance(x, ForeignKeyConstraint)] t_args = [] for field in table_args: for constraint in field.update_table_args(cls_): if ( not isinstance(constraint, ForeignKeyConstraint) or constraint.name not in fks ): t_args.append(constraint) elif isinstance(constraint, CheckConstraint): t_args.append(constraint) return res + tuple(t_args) return () new_base.define_table_args = classmethod(define_table_args) transformation_properties['table_args'] = True self.insert_in_bases_table_args(new_base, transformation_properties) self.insert_in_bases_mapper_args(new_base, transformation_properties)
[docs] def insert_in_bases_table_args(self, new_base, transformation_properties): """Add table __table_args__ in new_base :param new_base: the base to be put on front of all bases :param transformation_properties: the properties of the model """ if transformation_properties['table_args']: def __table_args__(cls_): return cls_.define_table_args() new_base.__table_args__ = declared_attr(__table_args__)
[docs] def insert_in_bases_mapper_args(self, new_base, transformation_properties): """Add table __mapper_args__ in new_base :param new_base: the base to be put on front of all bases :param transformation_properties: the properties of the model """ if transformation_properties['mapper_args']: def __mapper_args__(cls_): return cls_.define_mapper_args() new_base.__mapper_args__ = declared_attr(__mapper_args__)