【问题标题】:How can I write conditional clauses using SQLAlchemy's expression language?如何使用 SQLAlchemy 表达式语言编写条件子句?
【发布时间】:2013-03-14 23:06:14
【问题描述】:

所以,我编写了一个相当复杂的查询,它从两个表中获取并连接一堆数据。

SELECT
    /* Common attributes */
    carrier.name,
    carrier.notes,
    carrier.turnaround,

    /* Either per-reseller price, generic reseller price or default price */
    IFNULL(
        rsu.price,
        IF(
            (
                carrier.reseller_price != IS NOT NULL AND
                carrier.reseller_price != 0
            ),
            carrier.reseller_price,
            carrier.price
        )
    ) AS price,
    IFNULL(
        rsu.price_barred,
        IF(
            (
                carrier.reseller_price_barred IS NOT NULL AND
                carrier.reseller_price_barred != 0
            ),
            carrier.reseller_price_barred,
            carrier.price_barred
        )
    ) AS price_barred
FROM
    `core_carrier` AS carrier
LEFT OUTER JOIN
    `core_resellerunlock` AS rsu ON (
        rsu.carrier_id = carrier.id AND
        rsu.reseller_id = 1
    )

有人可以建议一种使用 SQLAlchemy 查询构建器重写它的方法吗?我不确定这些 SELECT ... IF 子句是否可行。

编辑:我不想使用 ORM 来执行此操作(据我所知,纯粹使用 SQLAlchemy ORM 执行此操作是不可能的)。我只是在寻找一种使用 SQLAlchemy 核心的或多或少的便携方式。

【问题讨论】:

  • 发布模型会有帮助。
  • 没有模型。你是说数据库模式吗?
  • SQLAlchemy 最好的特性是它的 ORM 特性。当我说模型时,我指的是 ORM。 Schema 没问题,但我希望你没有定义原始模式。我的意思是你甚至可以从你的 MySQL 控制台复制和粘贴模式。无论哪种方式,使用完整的架构都更容易阅读。
  • @CppLearner SQLAlchemy 由两个不同的部分组成——核心层和 ORM 层。我只使用核心。
  • 我认为家伙在使用 Core 时仍然需要声明模型,并且它只会为您节省状态管理中的所有开销。无论如何,我不确定这可以在 SqlAlchemy 中干净地完成。

标签: python mysql sqlalchemy


【解决方案1】:

您可以使用the case function 在查询中包含条件。这不会产生与您提供的完全相同的 SQL,但可以产生功能等效的东西。

这是一个简单的例子,carrierrsu 变量指代Table 对象,case 指上述函数:

join = carrier.join(rsu, (rsu.c.carrier_id == carrier.c.id) & (rsu.c.reseller_id == 1))
query = join.select([
    carrier.c.name,
    carrier.c.notes,
    carrier.c.turnaround,
    case([
        (
            rsu.c.price_barred == None,
            case([
                (
                    (carrier.c.reseller_price != None) & (carrier.c.reseller_price != 0),
                    carrier.c.reseller_price
                )
            ],
            else_=carrier.c.price
        )
    ]
])

您可能会发现创建一些帮助函数来表示您的更高级别的IFNULLIF 函数以提高查询的可读性很方便。例如:

def if_(expr, then, else_):
    return case([
        (expr, then)
    ], else_=else_)

【讨论】:

    猜你喜欢
    • 2019-08-04
    • 2012-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-03
    • 2021-12-24
    相关资源
    最近更新 更多