Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create many to many on one table

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?

like image 394
Matt Ellen Avatar asked Jun 22 '13 16:06

Matt Ellen


People also ask

How do you represent a many-to-many relationship in a table?

Junction table. When you need to establish a many-to-many relationship between two or more tables, the simplest way is to use a Junction Table. A Junction table in a database, also referred to as a Bridge table or Associative Table, bridges the tables together by referencing the primary keys of each data table.

How do I Create a one-to-many table in SQL?

How to implement one-to-many relationships when designing a database: Create two tables (table 1 and table 2) with their own primary keys. Add a foreign key on a column in table 1 based on the primary key of table 2. This will mean that table 1 can have one or more records related to a single record in table 2.

How do you solve a many-to-many relationship in a database?

Many-to-many (m:n) relationships add complexity and confusion to your model and to the application development process. The key to resolve m:n relationships is to separate the two entities and create two one-to-many (1:n) relationships between them with a third intersect entity.


1 Answers

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"
    )
like image 97
Sylvain Leroux Avatar answered Oct 22 '22 11:10

Sylvain Leroux