python - 当相关列不存在时 SQLAlchemy 忽略过滤器

标签 python postgresql orm sqlalchemy

我在使用 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}]

有人可以解释我哪里出错了吗?

最佳答案

您必须考虑左连接产生的 NULL 值,since != compares values and NULL is the absence of value ,所以 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)

关于python - 当相关列不存在时 SQLAlchemy 忽略过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47447356/

相关文章:

ruby - 将 ORM 添加到 Sinatra 应用程序;有没有问题少性能好的理想的?

java - 为什么 eclipselink 每次重新启动时都会消耗整个 AllocationSize?

java - JPA 不生成 "on delete set null"FK 限制

python - 为什么 tkinter 行为随机?

python - 如何在 SQLAlchemy 中的 python 中回滚 dataframe.to_sql?

postgresql - 如何将数据从 FileMaker Pro 导入到 PostgreSQL

java - 同一张表上的左连接

python - 你如何连接 Pandas 中的两行?

python - 检查变量是否为 SRE_Match

Python - 解决空页面中 Beautifulsoup 的 "object has no attribute"错误