问题
Flask-SQLAlchemy gives an example of how to create a many to many relationship. It is done between two different tables.
Is it possible to create a many to many relationship on the same table? For example a sister can have many sisters, who would also have many sisters. I have tried:
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'))
But when I try to add a sister to a girl I get:
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.
Is this possible? How should I be doing it?
回答1:
You are trying to build what is called an adjacency list. That is you have a table with foreign key to itself.
In your specific case it is a self referencial many to many relationship.
This is supported in SQLAlchemy as you will discover by following the previous link. The doc contains several examples.
Basically, you will need the primaryjoin and secondaryjoin arguments to establish how you would like to join the table. Straight from the doc:
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"
)
来源:https://stackoverflow.com/questions/17252816/create-many-to-many-on-one-table