假设我有一个activity
表和一个subscription
表。每个活动都有一个对其他对象的通用引用数组,每个订阅对同一组中的某个其他对象有一个通用引用。加入SQLAlchemy中的设置返回函数(SRF)和访问列表
CREATE TABLE activity (
id serial primary key,
ob_refs UUID[] not null
);
CREATE TABLE subscription (
id UUID primary key,
ob_ref UUID,
subscribed boolean not null
);
我想用设置返回函数unnest
的加入,使我能找到的“最深切的”匹配的预订,像这样:
SELECT id
FROM (
SELECT DISTINCT ON (activity.id)
activity.id,
x.ob_ref, x.ob_depth,
subscription.subscribed IS NULL OR subscription.subscribed = TRUE
AS subscribed,
FROM activity
LEFT JOIN subscription
ON activity.ob_refs @> array[subscription.ob_ref]
LEFT JOIN unnest(activity.ob_refs)
WITH ORDINALITY AS x(ob_ref, ob_depth)
ON subscription.ob_ref = x.ob_ref
ORDER BY x.ob_depth DESC
) sub
WHERE subscribed = TRUE;
但我想不出该怎么办第二次加入并访问列。我试图创建一个FromClause
like this:
act_ref_t = (sa.select(
[sa.column('unnest', UUID).label('ob_ref'),
sa.column('ordinality', sa.Integer).label('ob_depth')],
from_obj=sa.func.unnest(Activity.ob_refs))
.suffix_with('WITH ORDINALITY')
.alias('act_ref_t'))
...
query = (query
.outerjoin(
act_ref_t,
Subscription.ob_ref == act_ref_t.c.ob_ref))
.order_by(activity.id, act_ref_t.ob_depth)
但是导致这种SQL与另一个子查询:
LEFT OUTER JOIN (
SELECT unnest AS ob_ref, ordinality AS ref_i
FROM unnest(activity.ob_refs) WITH ORDINALITY
) AS act_ref_t
ON subscription.ob_refs @> ARRAY[act_ref_t.ob_ref]
...这失败,因为失踪和unsupportedLATERAL
关键字:
有一个表“活动”的条目,但它不能从这部分查询中引用。
那么,如何在不使用子查询的情况下为此SRF创建JOIN子句?还是有什么我失踪?
编辑1使用sa.text
与TextClause.columns
代替sa.select
让我拉近了许多:
act_ref_t = (sa.sql.text(
"unnest(activity.ob_refs) WITH ORDINALITY")
.columns(sa.column('unnest', UUID),
sa.column('ordinality', sa.Integer))
.alias('act_ref'))
但由于它包裹在括号中的条款产生的SQL失败:
LEFT OUTER JOIN (unnest(activity.ob_refs) WITH ORDINALITY)
AS act_ref ON subscription.ob_ref = act_ref.unnest
错误是syntax error at or near ")"
。我可以得到TextAsFrom
不能用圆括号包裹吗?