Python 相关列不存在时SQLAlchemy忽略筛选器

Python 相关列不存在时SQLAlchemy忽略筛选器,python,postgresql,orm,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(

使用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'
    )
用户项目(协会)

查询 我希望对projects表执行查询,以便结果包含有关项目的信息以及有关关联用户的信息(如果有)。我包括一个基于用户名的过滤器。我最终将通过RESTAPI将结果作为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)      

有人能解释一下我哪里出了问题吗

您必须考虑由左联接产生的空值,因此
NULL!='jane.doe'
为空,不是真的:


请注意,SQLAlchemy以一种特殊的方式处理与None相等的问题,并生成
为NULL
。如果希望不那么模棱两可,还可以使用
User.name.is(None)

您必须考虑由左联接产生的空值,因此
NULL!='jane.doe'
为空,不是真的:


请注意,SQLAlchemy以一种特殊的方式处理与None相等的问题,并生成
为NULL
。如果你想不那么模棱两可,你也可以使用
User.name.is(无)

谢谢!还有一件事——过滤器是由我的API以编程方式生成的,所以无论何时关联列上有过滤器,我都需要添加空过滤器(如您的帖子所示)。听起来对吗?若要说明某人实际希望执行IS NOT NULL筛选器的情况(在本例中不适用,因为列不可为NULL,但我仍需要说明),我可以执行以下操作:或(expr,Model.id==None)其中expr是用户添加的过滤器表达式,第二个表达式是自动添加的。有意义吗?不完全确定我是否遵循您的思路,但取决于您的API允许做什么,您不能只是在那里插入一个
或uuA(Something.Something==None,…)
。如果来自用户的谓词是
Something.Something==“黑暗面”
,该怎么办?谢谢!还有一件事——过滤器是由我的API以编程方式生成的,所以无论何时关联列上有过滤器,我都需要添加空过滤器(如您的帖子所示)。听起来对吗?若要说明某人实际希望执行IS NOT NULL筛选器的情况(在本例中不适用,因为列不可为NULL,但我仍需要说明),我可以执行以下操作:或(expr,Model.id==None)其中expr是用户添加的过滤器表达式,第二个表达式是自动添加的。有意义吗?不完全确定我是否遵循您的思路,但取决于您的API允许做什么,您不能只是在那里插入一个
或uuA(Something.Something==None,…)
。如果来自用户的谓词是
Something.Something==“黑暗面”
,该怎么办?
# 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)      
[{'id': 1, 'name': 'proj1', 'users.id': None, 'users.name': None}]
query = query.filter(
    Project.name == 'proj1',
    or_(User.name == None, User.name != 'jane.doe')
)