Python 如何在SQLAlchemy中查询关联表?
我正在尝试将SQL查询转换为SQLAlchemy查询,以便用户在GETAPI中使用。问题是我无法从关联表中查询任何内容。(我肯定我不知道方法) ORM: 工作SQL查询: 我遇到问题的SQLAlchemy查询: 使用上述SQLAlchemy查询时出现的错误:Python 如何在SQLAlchemy中查询关联表?,python,sql,sqlalchemy,flask-sqlalchemy,Python,Sql,Sqlalchemy,Flask Sqlalchemy,我正在尝试将SQL查询转换为SQLAlchemy查询,以便用户在GETAPI中使用。问题是我无法从关联表中查询任何内容。(我肯定我不知道方法) ORM: 工作SQL查询: 我遇到问题的SQLAlchemy查询: 使用上述SQLAlchemy查询时出现的错误: 如何使用SQLAlchemy执行与SQL查询等效的查询?好的,因此在Flask SQL alchemy中查询关联对象的关键是与用户角色进行外部连接。首先尝试联接所有表,然后进行筛选。我把答案贴在下面 query_user_role = Us
如何使用SQLAlchemy执行与SQL查询等效的查询?好的,因此在Flask SQL alchemy中查询关联对象的关键是与用户角色进行外部连接。首先尝试联接所有表,然后进行筛选。我把答案贴在下面
query_user_role = User.query.join(roles_users).join(Role).
filter((roles_users.c.user_id == User.id) & (roles_users.c.role_id == Role.id)).all()
查询关联表对象时不要忘记输入“c”。没有它,它就不会工作
还有一件事,不要忘记设置backref lazy='joined'我认为如果您的DAO代码库是面向ORM的,那么您可能应该尝试重新考虑您的场景,并利用您定义的sqlalchemy关系,因为它将为您处理必要的连接,以便查询用户的角色。 根据您的示例,类似于:
users = db.session.query(User).all()
for user in users:
for role in user.roles:
print((user.first_name, user.last_name, role.name))
与所选答案非常相似,但可能对某些人有帮助,请提供更多示例:
result = session.query(User.first_name, User.last_name, Role.name, roles_users).filter(
roles_users.c.user_id == User.id).filter(roles_users.c.role_id == Role.id).all()
也可以使用
select\u from
语句
这适用于将关联表声明为对象并使用flask\u用户时:
from flask_user import UserMixin
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class User(db.Model, UserMixin):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100, collation='NOCASE'),
nullable=False, server_default='')
password = db.Column(db.String(255), nullable=False, server_default='')
roles = db.relationship('Role', secondary='user_roles')
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(50), unique=True)
# Associatin Table:
class UserRoles(db.Model):
__tablename__ = 'user_roles'
id = db.Column(db.Integer(), primary_key=True)
user_id = db.Column(db.Integer(), db.ForeignKey('users.id',
ondelete='CASCADE'))
role_id = db.Column(db.Integer(), db.ForeignKey('roles.id',
ondelete='CASCADE'))
然后,您可以按如下方式查询用户角色:
from app.db_model import db, Broker, UserRoles
from flask_user import current_user
user_id = current_user.id
all_user_roles =\
(db.session.query(Role.name)
.select_from(UserRoles, Role)
.join(UserRoles)
.filter(UserRoles.user_id == user_id)
.all())
编辑:好的,使用当前用户更简单
# a list of all Role objects in roles
current_user.roles
# print out all names
print([role.name for role in current_user.roles])
布尔值和
应该是二进制的&
,否则会得到令人惊讶的结果。您还可以使用sqla中的和
函数。在本例中,左侧是“truthy”(一个sql表达式对象),因此布尔表达式的计算结果为右侧roles\u users.c.role\u id==role.id
。使用&
时,左侧和右侧必须用括号括起来过滤器((roles\u users.c.user\u id==user.id)&(roles\u users.c.role\u id==role.id))
感谢您的评论,进行了更改。请详细说明.c属性
result = session.query(User.first_name, User.last_name, Role.name, roles_users).filter(
roles_users.c.user_id == User.id).filter(roles_users.c.role_id == Role.id).all()
from flask_user import UserMixin
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class User(db.Model, UserMixin):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100, collation='NOCASE'),
nullable=False, server_default='')
password = db.Column(db.String(255), nullable=False, server_default='')
roles = db.relationship('Role', secondary='user_roles')
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(50), unique=True)
# Associatin Table:
class UserRoles(db.Model):
__tablename__ = 'user_roles'
id = db.Column(db.Integer(), primary_key=True)
user_id = db.Column(db.Integer(), db.ForeignKey('users.id',
ondelete='CASCADE'))
role_id = db.Column(db.Integer(), db.ForeignKey('roles.id',
ondelete='CASCADE'))
from app.db_model import db, Broker, UserRoles
from flask_user import current_user
user_id = current_user.id
all_user_roles =\
(db.session.query(Role.name)
.select_from(UserRoles, Role)
.join(UserRoles)
.filter(UserRoles.user_id == user_id)
.all())
# a list of all Role objects in roles
current_user.roles
# print out all names
print([role.name for role in current_user.roles])