【问题标题】:SQLAlchemy alias mixupSQLAlchemy 别名混淆
【发布时间】:2012-12-14 23:56:08
【问题描述】:

我对 SQLAlchemy 和别名有疑问。我正在尝试对一个名为 Task 的表进行自联接,但 SQLAlchemy 将我的别名表与非别名表混淆了。

我的查询要复杂得多,但这是一个简化版本:

baseTask = aliased(model.Task)

query = model.session.query(model.Task.name)\
       .select_from(baseTask)\
       .join((model.Task, model.Task.taskid==baseTask.taskid))

The resulting query looks like this:    
SELECT task_1.name 
FROM task AS task_1 INNER JOIN task ON task_1.taskid = task_1.taskid

正如您所见,它在选择和连接条件中都将未别名表与别名任务_1 混淆了。

通过在两个表上使用别名都可以:

baseTask = aliased(model.Task)
task = aliased(model.Task)

query = model.session.query(task.name)\
        .select_from(baseTask)\
        .join((task, task.taskid==baseTask.taskid))

This gives the desired result:
SELECT task_1.name 
FROM task AS task_2 INNER JOIN task AS task_1 ON task_1.taskid = task_2.taskid

当我在两个表上使用别名时,它不会混淆它们,结果查询正是我想要的。问题是由于各种原因我不能在我加入的表上使用别名,这是由于动态生成查询的应用程序设计。

我正在使用 SQLAlchemy 0.6.8,我尝试升级到 0.7.9,但仍然遇到此问题。关于如何解决这个问题的任何想法?

【问题讨论】:

    标签: sql sqlalchemy alias self-join


    【解决方案1】:

    不幸的是,select_from() 现在所做的两个特定事情之间存在一些功能重叠,其中之一是你可以说query(Task).select_from(<some SELECT statement>),它会根据<some SELECT statement> 重新定位“任务”,另一个是你可以告诉它首先从哪里加入。

    http://www.sqlalchemy.org/trac/ticket/2635 被添加到其中,也许在 0.8 中我们可以让它在这种特定情况下做出更好的决策。

    更新:感谢您对此的报告,我过去在自己的工作中也遇到过,但没能深入了解,这很简单。如果您现在想使用 0.8 提示,您的用例应该可以工作。

    这里是修复的一些背景:http://docs.sqlalchemy.org/en/latest/changelog/changelog_08.html#change-8d958f76ee47f7155365772401087d1f

    可能的 0.6.8 解决方法

    query = session.query(Task.name)
    
    query._from_obj += (baseTask._AliasedClass__alias, )
    
    query = query.join((Task, Task.taskid == baseTask.taskid))
    

    【讨论】:

    • 这太棒了,非常感谢,我对快速响应和解决方案印象深刻。 :) 我们的应用程序用于生产,从 0.6.8 升级是一个相当大的决定。我尝试优化的查询是我们应用程序的核心,目前我必须以次优的方式重写它。你知道有什么办法可以解决吗?
    • 0.6.8 中的 select_from() 模型甚至不如 0.7 的一致。我在上面添加了一个 very hacky 代码示例,它可能会让你度过一天。
    • 谢谢zzzeek,非常感谢!
    猜你喜欢
    • 2011-09-04
    • 2012-09-21
    • 1970-01-01
    • 2014-09-20
    • 2018-05-22
    • 2014-05-30
    • 2012-05-24
    • 2017-03-08
    • 2014-04-12
    相关资源
    最近更新 更多