SQLAlchemy生成错误的SQL(用于别名和自联接)?

时间:2013-10-11 09:52:01

标签: python sql orm sqlalchemy

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文档的所有独立别名/加入/自联接测试都可以正常工作。

可能出了什么问题?任何指针都将非常感激。

顺便说一句,我正在映射多个数据库,是否与此问题有关?

2 个答案:

答案 0 :(得分: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的别名。

答案 1 :(得分:0)

问题是由SQLAlchemy的错误使用引起的,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'