2013-10-11 44 views
0

SQLAlchemy的0.8產生錯誤的SQL以下簡單的自我加入 -SQLAlchemy生成錯誤的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文檔都工作正常。

出了什麼問題?任何指針將不勝感激。

順便說一句,我映射多個數據庫,它可能與此問題有關?

回答

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的別名。

+0

非常感謝你的時間邁克!無法再現這種神祕的行爲正是我無法提出展示問題的完整測試的原因 - 讓我在整個週日投資,看看我能否找到更多線索。但至少該片段是源代碼的文字摘錄,「DJ1」實際上是ScheduledJob的別名。 – Jerry

0

問題是由SQLAlchemy中的不正確使用,它映射來自同一基座上,用同樣的__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'