2013-06-22 18 views
5

Flask-SQLAlchemy daje example, jak stworzyć wiele do wielu relacji. Odbywa się między dwiema różnymi tabelami.Stwórz wiele dla wielu na jednej tabeli

Czy można utworzyć wiele do wielu relacji na tym samym stole? Na przykład siostra może mieć wiele sióstr, które również mają wiele sióstr. Próbowałem:

girl_sister_map = db.Table('girl_sister_map', 
         db.Column('girl_id', 
           db.Integer, 
           db.ForeignKey('girl.id')), 
         db.Column('sister_id', 
           db.Integer, 
           db.ForeignKey('girl.id'))) 

class Girl(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String) 
    sisters = db.relationship('Girl', 
           secondary=girl_sister_map, 
           backref=db.backref('othersisters', lazy='dynamic')) 

Ale gdy próbuję dodać siostra dziewczynki uzyskać:

sqlalchemy.exc.AmbiguousForeignKeysError: Could not determine join condition between parent/child tables on relationship Girl.sisters - there are multiple foreign key paths linking the tables via secondary table 'girl_sister_map'. Specify the 'foreign_keys' argument, providing a list of those columns which should be counted as containing a foreign key reference from the secondary table to each of the parent and child tables.

Czy to możliwe? Jak powinienem to robić?

Odpowiedz

9

Próbujesz zbudować coś, co nazywa się adjacency list. To znaczy, że masz stół z obcym kluczem dla siebie.

W konkretnym przypadku jest to self referencial many to many relationship.

Jest to obsługiwane w SQLAlchemy, ponieważ zostanie wykryte, wykonując poprzedni link. Dokument zawiera kilka przykładów.

Zasadniczo potrzebne będą argumenty primaryjoin i secondaryjoin w celu ustalenia, w jaki sposób chcesz dołączyć do tabeli. Prosto z dokumentu:

Base = declarative_base() 

node_to_node = Table("node_to_node", Base.metadata, 
    Column("left_node_id", Integer, ForeignKey("node.id"), primary_key=True), 
    Column("right_node_id", Integer, ForeignKey("node.id"), primary_key=True) 
) 

class Node(Base): 
    __tablename__ = 'node' 
    id = Column(Integer, primary_key=True) 
    label = Column(String) 
    right_nodes = relationship("Node", 
         secondary=node_to_node, 
         primaryjoin=id==node_to_node.c.left_node_id, 
         secondaryjoin=id==node_to_node.c.right_node_id, 
         backref="left_nodes" 
    ) 
Powiązane problemy