2016-12-21 10 views
1

Я пытаюсь преобразовать SQL-запрос в запрос SQLAlchemy для пользователя внутри get API. Проблема в том, что я не могу ничего запросить из таблицы ассоциаций. (Я уверен, что не знаю метода).Как запросить таблицу ассоциаций в SQLAlchemy?

ORM:

roles_users = db.Table(
    'roles_users', 
    db.Column('user_id', db.Integer(), db.ForeignKey('user.id')), 
    db.Column('role_id', db.Integer(), db.ForeignKey('role.id')) 
    ) 

class Role(db.Model, RoleMixin): 
    id = db.Column(db.Integer(), primary_key=True) 
    name = db.Column(db.String(50), unique=True) 
    description = db.Column(db.String(255)) 

    def __str__(self): 
     return self.name 

class User(db.Model, UserMixin): 
    id = db.Column(db.Integer, primary_key=True) 
    first_name = db.Column(db.String(50)) 
    last_name = db.Column(db.String(50)) 
    email = db.Column(db.String(50), unique=True) 
    password = db.Column(db.String(255)) 
     . 
     . 
     . 
    roles = db.relationship('Role', secondary=roles_users, 
         backref=db.backref('users', lazy='dynamic')) 

    def __str__(self): 
     return self.email 

Рабочий SQL-запрос:

select first_name, last_name, role.name from user 
    join roles_users 
     join role on user.id = roles_users.user_id 
      and role.id = roles_users.role_id; 

SQLAlchemy запрос, у меня возникают проблемы с:

roles_users.query.join(Role).join(User) 
    .filter(roles_users.user_id == User.id and 
     roles_users.role_id == Role.id).all() 

ошибка, я получаю, используя выше SQLAlchemy запроса:

AttributeError: 'Table' object has no attribute 'query' 

Как выполнить эквивалент моего SQL запроса с помощью SQLAlchemy?

ответ

4

Итак, ключ к запросу объекта ассоциации в алкемии Flask-Sql заключается в том, чтобы сделать внешнее соединение с role_users. Сначала попробуйте присоединиться ко всем таблицам, а затем отфильтровать потом. Я отправляю ответ ниже.

query_user_role = User.query.join(roles_users).join(Role). 
filter(roles_users.c.user_id == User.id and roles_users.c.role_id == Role.id).all() 

Не забудьте поставить 'c' при запросе объекта таблицы связей. Без этого это не сработает. более

Одна вещь, не забудьте установить backref ленивым = «присоединился»

+2

Логический 'and' должен быть двоичным' & ', или вы получите удивительные результаты. Вы также можете использовать функцию 'and_' из sqla. В этом случае левая сторона является «правдивой» (объект выражения sql), поэтому логическое выражение оценивается в правой части 'role_users.c.role_id == Role.id'. –

+0

При использовании '&' левой и правой сторон должны быть заключены в круглые скобки 'filter ((role_users.c.user_id == User.id) & (role_users.c.role_id == Role.id))' –