2016-03-24 14 views
0

我在SQLAlchemy的兩個型號,我已經自動加入一個外鍵,像這樣:指定聯接條件SQLAlchemy的ORM不用擔心外鍵

class Parent(Base): 
    __tablename__ = 'parents' 

    id = Column(Integer, primary_key=True) 
    name = Column(String(300), nullable=False) 
    metadata_id = Column(Integer, nullable=True, index=True) 

class Child(Base): 
    __tablename__ = 'children' 

    id = Column(Integer, primary_key=True) 
    name = Column(String(300), nullable=False) 
    parent_metadata_id = \ 
     Column(ForeignKey('parents.metadata_id'), 
       nullable=True, primary_key=True) 
    parent = relationship(u'Parent') 

這工作得很好,我可以得到很容易從訪問父它的孩子。現在,由於技術原因超出了這個問題的範圍,我不得不擺脫我的分貝中的外鍵。我試圖在SQLAlchemy中解決這個問題,但沒有任何替換代碼(使用主要連接或backrefs)工作。我看到另一個回答here,只是說對SQLAlchemy撒謊,並告訴它我有外鍵關係,但這使得Alembic嘗試在我自動生成的每個新修訂版本上創建外鍵關係,這真的很煩人。什麼是正確的方法來做到這一點?

+0

Downvoter,你能解釋一下你的問題與我的問題嗎? – Eli

回答

3

爲了使relationship工作,你可以指定顯式連接條件:

parent = relationship(Parent, primaryjoin=parent_metadata_id == Parent.metadata_id) 

要加入到Child工作,你可以指定關係的,而不是實體:

session.query(Child).join(Child.parent) 

或者,請明確指定加入條件:

session.query(Child).join(Child, Child.parent_metadata_id == Parent.metadata_id) 

對SQLAlchemy說謊也有效。你可以通過指定include_object參數來讓alembic忽略外鍵:

class Child(Base): 
    ... 
    parent_metadata_id = Column(ForeignKey(...), info={"skip_autogenerate": True}, ...) 

def include_object(object, name, type_, reflected, compare_to): 
    if not reflected and object.info.get("skip_autogenerate", False): 
     return False 
    return True 
+0

這對我有用,一旦我把'info'參數外部的ForeignKey(...)。我編輯了你的答案以反映這一點。謝謝您的幫助! – Eli

+0

@Eli這讓alembic完全跳過了這一列。也許你使用的是舊版本的alembic(它在0.7.1之前沒有用於支持'include_object'中的外鍵)? – univerio

+0

你是對的。我現在在Alembic 0.8.5上,我可以將'info'放在ForeignKey(...)中,但現在它只是被忽略。當它放在一個列中時它工作正常,但正如你所說,整個列被忽略。 – Eli