2012-09-01 111 views
0

在SQLAlchemy中,我想编写一套表A的记录然后在表BI想写一个纪录A.引用了(先前)未知数量的记录SQLAlchemy的多个外键

用python来说,我会创建类A和B,然后在B中包含一个包含A类对象的列表。

可以这样做吗?

+0

欢迎来到Stack Overflow!我们鼓励你[研究你的问题](http://stackoverflow.com/questions/how-to-ask)。如果你已经[尝试了某些东西](http://whathaveyoutried.com/),请将其添加到问题中 - 如果没有,请先研究并尝试您的问题,然后再回来。 – 2012-09-27 16:26:17

回答

1

这不是一个真正的SQLAlchemy问题,而是一个基本的关系表问题。

您不是在谈论一对多的关系,或者是多对多的关系,SQLAlchemy都支持开箱即用的关系。

一一对多

一个一对多的关系是基本遏制之一;一个部门有很多员工,但每个员工只有一个部门。在这种情况下,只有一个外出关系的类获得外键,因此员工引用了部门,而不是相反。

example from the SQLAlchemy documentation给出如下:

class Parent(Base): 
    __tablename__ = 'parent' 
    id = Column(Integer, primary_key=True) 
    children = relationship("Child") 

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

因此,如果您A类只能是一个B集的一部分,使用这种模式。

许多一对多

一个多一对多的关系是一个双方都可以参考对方的多个实例。想想员工和项目;一名员工可以成为多个项目的一部分,而一个项目可能涉及多名员工。

在SQL中,这种关系需要一个关联表,一个额外的数据库表,用于存放两个链接类型之间的映射。 SQLAlchemy documentation on many-to-many relationships文件清楚如何做到这一点;这里是例如:

association_table = Table('association', Base.metadata, 
    Column('left_id', Integer, ForeignKey('left.id')), 
    Column('right_id', Integer, ForeignKey('right.id')) 
) 

class Parent(Base): 
    __tablename__ = 'left' 
    id = Column(Integer, primary_key=True) 
    children = relationship("Child", 
        secondary=association_table) 

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

使用此图案如果每个A对象可以是多于一个的B集的一部分。

+0

在发布问题之前,我实际上阅读了这篇文章,但我回过头再读一遍。我仍然不明白这将如何工作。这association_table让我有许多1对1的关系,当你总体看他们是我猜想的一种多对多关系。但不是我想要的那种(这是一个从Child到Parent的可变长度的ForeignKeys列表,我想我可以将ID存储在一个二进制块中... –

+0

@ArewrewStone:这就是关系规范化的工作方式。为你寻找可变长度的外键搜索'多对多'和'sql'并阅读这个概念;这不仅仅限于SQLAlchemy单独使用 –

+0

@ArewrewStone:这样看:如果你想查询关联表的所有关系,其中TypeB_id =“foobar”,你会得到一个有限的行列表,每一行都是一个TypeA项目的ID,长度可变,这就是数据库如何有效地存储这些关系。 –