Ошибка при построении составного «вторичного» соединения через пять таблиц в sqlalchemy - PullRequest
0 голосов
/ 30 мая 2019

Я создаю шесть таблиц для управления ролью пользователя.

таблицы: пользователь, группа, пользовательская группа, пользовательская роль, групповая роль, роль

отношения между таблицами приведены ниже

пользователь -> user_role -> роль

user -> user_group -> group_role -> role

Я пытаюсь использовать составные «вторичные» объединения для построения отношений между пользователем и ролью. но я на самом деле не знаю, как работают params вторичные, вторичные, первичные, я пытаюсь вот так, но получил

sqlalchemy.exc.InvalidRequestError: Класс не имеет сопоставленного столбца с именем 'get_children'

эти модели основаны на фляге-sqlalchemy

class Role(db.Model):
    __tablename__ = 'role'
    role_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(100), unique=True, nullable=False)
    permissions = db.relationship("Permission", secondary='role_permission')

class User(db.Model):
    __tablename__ = 'user'
    user_id = db.Column(db.BigInteger, primary_key=True)
    username = db.Column(db.String(100), nullable=False)
    _password = db.Column('password', db.String(100), nullable=False)
    roles = db.relationship('Role',
                            secondary='join(UserGroup, GroupRole, UserGroup.group_id == GroupRole.group_id).'
                                      'join(UserRole, Role, UserRole.role_id == Role.role_id)',
                            primaryjoin='and_(User.user_id == UserGroup.user_id, '
                                        'User.user_id == UserRole.user_id)',
                            secondaryjoin='GroupRole.role_id == Role.role_id',
                            uselist=False)


class Group(db.Model):
    __tablename__ = 'group'
    group_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(190), nullable=False, unique=True)


class UserGroup(db.Model):
    __tablename__ = 'user_group'
    user_group_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    user_id = db.Column(db.BigInteger, db.ForeignKey('user.user_id'))
    group_id = db.Column(db.Integer, db.ForeignKey('group.group_id'))
    user = db.relationship('User', backref=db.backref('groups'))
    group = db.relationship('Group', backref=db.backref('users'))


class UserRole(db.Model):
    __tablename__ = 'user_role'
    user_role_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    user_id = db.Column(db.BigInteger, db.ForeignKey('user.user_id'))
    role_id = db.Column(db.Integer, db.ForeignKey('group.group_id'))


class GroupRole(db.Model):
    __tablename__ = 'group_role'
    group_role_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    group_id = db.Column(db.Integer, db.ForeignKey('group.group_id'))
    role_id = db.Column(db.Integer, db.ForeignKey('role.role_id'))
>>> from user.models import User
>>> User.query.join(User.roles).all()
Traceback (most recent call last):
......
......
......
sqlalchemy.exc.InvalidRequestError: Class <class 'auth.models.Role'> does not have a mapped column named 'get_children'

больше трассировки


> Traceback (most recent call last):   File "<console>", line 1, in
> <module>   File
> "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\flask_sqlalchemy\__init__.py",
> line 517, in __get__
>     mapper = orm.class_mapper(type)   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\orm\base.py",
> line 441, in class_mapper
>     mapper = _inspect_mapped_class(class_, configure=configure)   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\orm\base.py",
> line 420, in _inspect_mapped_class
>     mapper._configure_all()   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\orm\mapper.py",
> line 1337, in _configure_all
>     configure_mappers()   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\orm\mapper.py",
> line 3229, in configure_mappers
>     mapper._post_configure_properties()   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\orm\mapper.py",
> line 1947, in _post_configure_properties
>     prop.init()   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\orm\interfaces.py",
> line 196, in init
>     self.do_init()   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\orm\relationships.py",
> line 1861, in do_init
>     self._setup_join_conditions()   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\orm\relationships.py",
> line 1941, in _setup_join_conditions
>     can_be_synced_fn=self._columns_are_mapped,   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\orm\relationships.py",
> line 2248, in __init__
>     self._annotate_fks()   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\orm\relationships.py",
> line 2479, in _annotate_fks
>     self._annotate_present_fks()   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\orm\relationships.py",
> line 2496, in _annotate_present_fks
>     secondarycols = util.column_set(self.secondary.c)   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\util\langhelpers.py",
> line 855, in __get__
>     obj.__dict__[self.__name__] = result = self.fget(obj)   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\sql\selectable.py",
> line 620, in columns
>     self._populate_column_collection()   File "<string>", line 1, in <lambda>   File
> "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\sql\selectable.py",
> line 841, in _populate_column_collection
>     (c for c in columns if c.primary_key), self.onclause   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\sql\util.py",
> line 675, in reduce_columns
>     visitors.traverse(clause, {}, {"binary": visit_binary})   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\sql\visitors.py",
> line 281, in traverse
>     return traverse_using(iterate(obj, opts), obj, visitors)   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\sql\visitors.py",
> line 229, in iterate
>     children = obj.get_children(**opts)   File "c:\users\luvjo\.virtualenvs\lay_manager-xsrpfj9p\lib\site-packages\sqlalchemy\ext\declarative\clsregistry.py",
> line 222, in __getattr__
>     % (self.cls, key) sqlalchemy.exc.InvalidRequestError: Class <class 'auth.models.Role'> does not have a mapped column named 'get_children'
...