2013-06-22 2 views
5

Flask-SQLAlchemy gibt eine example zum Erstellen einer Beziehung viele zu viele. Es wird zwischen zwei verschiedenen Tabellen durchgeführt.Erstellen Sie viele zu vielen auf einer Tabelle

Ist es möglich, eine Viele-zu-viele-Beziehung auf derselben Tabelle zu erstellen? Zum Beispiel kann eine Schwester viele Schwestern haben, die auch viele Schwestern haben würden. Ich habe versucht:

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')) 

Aber wenn ich versuche, eine Schwester zu einem Mädchen, das ich bekommen hinzuzufügen:

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.

Ist das möglich? Wie soll ich es machen?

Antwort

9

Sie versuchen zu bauen, was ein adjacency list genannt wird. Das heißt, Sie haben eine Tabelle mit Fremdschlüssel an sich. In Ihrem speziellen Fall ist es ein self referencial many to many relationship.

Dies wird in SQLAlchemy unterstützt, wie Sie feststellen werden, indem Sie dem vorherigen Link folgen. Das Dokument enthält mehrere Beispiele.

Grundsätzlich benötigen Sie die Argumente primaryjoin und secondaryjoin, um festzulegen, wie Sie der Tabelle beitreten möchten. Direkt aus dem Dokument:

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" 
    ) 
Verwandte Themen