1

SQLAlchemy 0.8 为以下简单的自连接生成错误的 SQL——

class ScheduledJob(Base):
    Id = Column('Id', Integer, primary_key=True)
    DependentJob1 = Column('DependentJob1', Integer)

DJ1 = aliased(ScheduledJob)
query = dbsession.query(ScheduledJob.Id, DJ1.Id).outerjoin(
        DJ1, ScheduledJob.DependentJob1==DJ1.Id)
print query

并打印错误的 SQL——

SELECT "ScheduledJob"."Id" AS "ScheduledJob_Id"
FROM "ScheduledJob" LEFT OUTER JOIN "ScheduledJob" AS "ScheduledJob_1" ON
"ScheduledJob"."DependentJob1" = "ScheduledJob"."Id"

虽然它应该是——

SELECT "ScheduledJob"."Id" AS "ScheduledJob_Id",
"ScheduledJob_1"."Id" AS "ScheduledJob_1_Id"
FROM "ScheduledJob" LEFT OUTER JOIN "ScheduledJob" AS "ScheduledJob_1" ON
"ScheduledJob"."DependentJob1" = "ScheduledJob_1"."Id"

更令人费解的是,我在 SQLAlchemy 文档之后尝试的所有独立别名/连接/自连接测试都可以正常工作。

可能出了什么问题?任何指针将不胜感激。

顺便说一句,我正在映射多个数据库,这可能与这个问题有关吗?

4

2 回答 2

1

无法重现。测试用例在 0.8.2、0.8.1、0.8.0 上运行,结果正确:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class ScheduledJob(Base):
    __tablename__ = 'ScheduledJob'

    Id = Column('Id', Integer, primary_key=True)
    DependentJob1 = Column('DependentJob1', Integer)

session = Session()

DJ1 = aliased(ScheduledJob)
query = session.query(ScheduledJob.Id, DJ1.Id).outerjoin(DJ1, ScheduledJob.DependentJob1==DJ1.Id)
print query

输出:

SELECT "ScheduledJob"."Id" AS "ScheduledJob_Id", "ScheduledJob_1"."Id" AS "ScheduledJob_1_Id" 
FROM "ScheduledJob" LEFT OUTER JOIN "ScheduledJob" AS "ScheduledJob_1" ON "ScheduledJob"."DependentJob1" = "ScheduledJob_1"."Id"

我怀疑在您的实际应用程序中,“DJ1”实际上并不是 ScheduledJob 的别名。

于 2013-10-12T22:21:29.167 回答
1

该问题是由 SQLAlchemy 的错误使用引起的,它映射了从同一个 Base 扩展的多个表,并且具有相同的__tablename__

一旦我将它们分离到不同的基地,一切都很好 -

class ScheduledJobMixin(object):
    Id = Column('Id', Integer, primary_key=True)
    ...

Remote_Base = declarative_base()
class RemoteScheduledJob(ScheduledJobMixin, Remote_Base):
    __tablename__ = 'ScheduledJob'

Base = declarative_base()
class ScheduledJob(ScheduledJobMixin, Base):
    __tablename__ = 'ScheduledJob'
于 2013-10-17T10:34:18.707 回答