2010-08-12 62 views
35

什么是使用声明式在SQLAlchemy中创建一对一关系的最佳方式?sqlalchemy:与声明的一对一关系

我有两个表,foobar,我想foo.bar_id链接到bar。问题在于,这是一种单向的一对一关系。 bar一定不知道关于foo的任何信息。对于每一个foo,都会有一个并且只有一个bar

理想的情况下,选择一个Foo后,我可以做这样的事情:

myfoo.bar.whatever = 5 

什么来完成这个使用声明的最佳方式?

回答

28

如果您想要一个真正的一对一关系,您还必须在关系定义中使用“uselist = False”。

bar_id = Column(Integer, ForeignKey(Bar.id)) 
bar = relationship(Bar, uselist=False) 
+6

这并不完全正确,因为如果连接的FK与关系定义在同一个类中,uselist关键字不会有任何影响。请参阅[答案chadwick.boulay](http://stackoverflow.com/a/9611874/851737)以获得正确的解决方案。 – schlamar 2012-04-17 06:07:54

2

事实证明,这实际上很容易。在您的Foo模型中:

bar_id = Column(Integer, ForeignKey(Bar.id)) 
bar = relationship(Bar) 
81

0.7 explains this nicely的文档:

class Parent(Base): 
    __tablename__ = 'parent' 
    id = Column(Integer, primary_key=True) 
    child = relationship("Child", uselist=False, backref="parent") 

class Child(Base): 
    __tablename__ = 'child' 
    id = Column(Integer, primary_key=True) 
    parent_id = Column(Integer, ForeignKey('parent.id')) 

OR

class Parent(Base): 
    __tablename__ = 'parent' 
    id = Column(Integer, primary_key=True) 
    child_id = Column(Integer, ForeignKey('child.id')) 
    child = relationship("Child", backref=backref("parent", uselist=False)) 

class Child(Base): 
    __tablename__ = 'child' 
    id = Column(Integer, primary_key=True) 
3

我想,如果它是一个真正的一对一的关系,我们应该添加一个唯一性约束外键,以便另一父母不能有其他父母的孩子!像这样:

class Parent(Base): 
    __tablename__ = 'parent' 
    id = Column(Integer, primary_key=True) 
    child_id = Column(Integer, ForeignKey('child.id'), unique=True) 
    child = relationship("Child", backref=backref("parent", uselist=False)) 

class Child(Base): 
    __tablename__ = 'child' 
    id = Column(Integer, primary_key=True)