sqlalchemy:add_ inside outerjoin不会应用别名

时间:2018-04-09 16:43:19

标签: python sqlalchemy

我想在sqlalchemy查询中过滤非活动元素。

我能够使用过滤器来进行简单查询,但是当我在关系中加入时,如果其中一个关系不存在,过滤器就不会返回结果。

我看到了一些解决方案,比如生成左侧表达式但我在所有模型中都使用了泛型函数,而我无法创建它。

一个选项是在关系模型中添加此过滤器,但我想避免它,因为它不是全局过滤器,它仅适用于某些情况。

我想在join子句中添加过滤器以获得结果,尽管该关系没有任何条目。

我想创建的SQL是:

SELECT *
FROM customers 
LEFT OUTER JOIN distributors AS distributors_1 ON distributors_1.id = customers.distributor_id AND distributors_1._active IS true
WHERE customers.distributor_id = 1 AND customers._active IS true

使用sqlachemy我试图根据模型创建查询,因为它是参数化的。

当前型号:

class Customer(CommonColumns):
    __tablename__ = 'customers'
    id = Column(Integer, primary_key=True, autoincrement=True)
    _active = Column(Boolean(1), default=True, nullable=False)
    name = Column(String(12), nullable=False, unique=True)
    distributor_id = Column(Integer, ForeignKey('distributors.id', ondelete='CASCADE'), nullable=False)
    distributor = relationship("Distributor", lazy="noload")

class Distributor(CommonColumns):
    __tablename__ = 'distributors'
    id = Column(Integer, primary_key=True, autoincrement=True)
    _active = Column(Boolean(1), default=True, nullable=False)
    name = Column(String(12), nullable=False, unique=True)
    customers = relationship("Customer", lazy="noload")

查询生成:

model = Customer
relationship = "distributor"
rel_model = getattr(model, relationship) --> *Customer.distributor*
alias = aliased(relationship)

query.outerjoin(alias, and_(rel_model, getattr(alias, "_active").is_(True)))
options = contains_eager(rel_model, alias=alias)
query = query.options(options)

这样做sqlalchemy没有在查询中创建正确的别名,结果是以下sql,这不是一个有效的sql:

    SELECT *
        FROM customers 
        LEFT OUTER JOIN distributors AS distributors_1 ON **distributors.id** = customers.distributor_id AND distributors_1._active IS true
        WHERE customers.distributor_id = 1 AND customers._active IS true

--> Unknown column 'distributors.id' in 'on clause'

如您所见,生成 distributors.id 而不是别名 distributors_1.id

不使用add_函数,别名正常工作并生成有效的SQL。

问题假设

我认为问题出在 rel_model 变量上,无法将 Customer.distributor 转换为别名版本,因为它位于and_ function

使用 outerjoin 中的和_ 函数不会在add_表达式中应用别名。

我无法编写外连接左表达式,因为我的函数是通用的,我不知道哪个是关系中使用的列。

我无法转换 rel_model 变量,因为我不知道关系中使用的列是哪个。

有一种方法可以从sqlalchemy模型生成左表达式吗?例如,恢复关系中使用的列?

我可以以外连接在sql语句中正确添加别名的方式使用add_函数吗?

0 个答案:

没有答案