gpt4 book ai didi

python - 按 union 的 SQLAlchemy 查询中的标记列过滤

转载 作者:太空宇宙 更新时间:2023-11-04 05:09:38 25 4
gpt4 key购买 nike

实现标题几乎等同于How to use a labelled column in sqlalchemy filter?我相信这是一个单独的问题。

为了大大简化我的问题:假设我有两个查询,每个查询都返回我想要的结果的一个子集,我将它们联合在一起:

initial_task = "initial_task"
scheduled_task = "scheduled_task"

initial = session.query(Task.task_id,
User.signup_date.label('due_date'),
literal(initial_task).label('type'))\
.join(Task.user)

schedule = session.query(Task.task_id,
Schedule.due_date.label('due_date'),
literal(scheduled_task).label('type'))\
.join(Task.schedule)

tasks = initial.union_all(schedule)

需要说明的是:我意识到这个例子可以在没有 union 的情况下重写;我的实际用例有五个独立的查询,除了结果可强制转换为这种正常格式之外几乎没有任何共同点。

如何过滤 tasks 以仅包含 2017 年 4 月 1 日之后到期的任务?从概念上讲,类似于:

tasks.filter(tasks.c.due_date >= datetime(2017, 4, 1))

主要问题是我不知道如何以一般方式引用 due_date 列。我从文档中尝试的所有内容似乎都在谈论较低级别的 API,并且在 ORM 层上导致:

'Query' object has no attribute 'c'

最佳答案

Query.union_all()方法产生一个新的 Query 实例,它与 sql.expression.union_all() 产生的 CompoundSelect 有点不同。构建,正如你所指出的。你可以使用 literal_column()过滤查询:

In [18]: tasks.filter(literal_column('due_date') >= datetime(2017, 4, 1))
Out[18]: <sqlalchemy.orm.query.Query at 0x7f1d2e191b38>

In [19]: print(_)
SELECT anon_1.task_id AS anon_1_task_id, anon_1.due_date AS anon_1_due_date, anon_1.type AS anon_1_type
FROM (SELECT task.id AS task_id, user.signup_date AS due_date, ? AS type
FROM task JOIN user ON task.id = user.task_id UNION ALL SELECT task.id AS task_id, schedule.due_date AS due_date, ? AS type
FROM task JOIN schedule ON task.id = schedule.task_id) AS anon_1
WHERE due_date >= ?

另一方面,您可以只在各自的日期列上分别过滤联合的各个部分。

最后,如果这更接近您的实际目标(被您的简化示例隐藏),您可以将联合包装在子查询中:

In [26]: tasks_sq = tasks.subquery()

In [27]: session.query(tasks_sq).\
...: filter(tasks_sq.c.due_date >= datetime(2017, 4, 1))
Out[27]: <sqlalchemy.orm.query.Query at 0x7f1d2e1d4828>

In [28]: print(_)
SELECT anon_1.task_id AS anon_1_task_id, anon_1.due_date AS anon_1_due_date, anon_1.type AS anon_1_type
FROM (SELECT anon_2.task_id AS task_id, anon_2.due_date AS due_date, anon_2.type AS type
FROM (SELECT task.id AS task_id, user.signup_date AS due_date, ? AS type
FROM task JOIN user ON task.id = user.task_id UNION ALL SELECT task.id AS task_id, schedule.due_date AS due_date, ? AS type
FROM task JOIN schedule ON task.id = schedule.task_id) AS anon_2) AS anon_1
WHERE anon_1.due_date >= ?

关于python - 按 union 的 SQLAlchemy 查询中的标记列过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43328751/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com