2016-03-24 28 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