我在使用SQLalchemy构建查询时遇到问题。以下是我定义的模型的简化表示:
项目
class Project(Base):
__tablename__ = 'project'
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False, unique=True)
# User associations
users = relationship(
'User',
secondary='user_project_association'
)
用户
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False, unique=True)
# Project associations
projects = relationship(
'Project',
secondary='user_project_association'
)
用户< - >项目(协会)
class UserProjectAssociation(Base):
__tablename__ = 'user_project_association'
# User association.
user_id = Column(Integer, ForeignKey('user.id'), primary_key=True)
user = relationship('User', backref='project_associations')
# Project association.
project_id = Column(Integer, ForeignKey('project.id'), primary_key=True)
project = relationship('Project', backref='user_associations')
我想对项目表执行查询,以便结果包含有关项目的信息以及有关相关用户的信息 - 如果有的话。我包括一个基于用户名的过滤器。我最终将通过REST API将结果作为JSON发送,因此我更喜欢结果为python {dict}对象而不是SQLAlchemy对象。我正在执行的查询如下:
# Add return fields
query = session.query(
Project.id,
Project.name,
User.id.label('users.id'),
User.name.label('users.name')
)
# Add join statements
query = query.outerjoin(User, Project.users)
# Add filters
query = query.filter(
Project.name == 'proj1',
User.name != 'jane.doe' # <--- I think this is causing the issue.
)
# Execute
results = query.all()
data = [result._asdict() for result in results]
print(data)
数据库包含一个名为 proj1 的项目,该项目没有任何关联用户。在此特定方案中,我正在过滤用户列,并且用户关联不存在。但是,我仍然期望在我的结果中为项目获取一行,但查询返回一个空列表。我期待的结果看起来像这样:
[{'id': 1, 'name': 'proj1', 'users.id': None, 'users.name': None}]
有人可以解释我哪里错了吗?
答案 0 :(得分:2)
您必须考虑左连接since !=
compares values and NULL is the absence of value产生的NULL值,因此NULL != 'jane.doe'
的结果为NULL,而不是 true :
query = query.filter(
Project.name == 'proj1',
or_(User.name == None, User.name != 'jane.doe')
)
请注意,SQLAlchemy以特殊方式处理与None的相等性,并生成IS NULL
。如果你想减少歧义,你也可以使用User.name.is_(None)
。