0

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

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 核心的或多或少的可移植方式。

4

1 回答 1

2

您可以使用函数在查询case包含条件。这不会产生您提供的 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_)
于 2013-03-17T02:09:10.170 回答