Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Many-to-many self-referential relationship in sqlalchemy

I'm trying to make a self-referential many-to-many relationship (it means that Line can have many parent lines and many child lines) in sqlalchemy like this:

Base = declarative_base()

class Association(Base):
 __tablename__ = 'association'

 prev_id = Column(Integer, ForeignKey('line.id'), primary_key=True)                            
 next_id = Column(Integer, ForeignKey('line.id'), primary_key=True)


class Line(Base):
 __tablename__ = 'line'

 id = Column(Integer, primary_key = True)
 text = Column(Text)
 condition = Column(Text)
 action = Column(Text)

 next_lines = relationship(Association, backref="prev_lines")



class Root(Base):
 __tablename__ = 'root'

 name = Column(String, primary_key = True)
 start_line_id = Column(Integer, ForeignKey('line.id'))

 start_line = relationship('Line')

But I get the following error: sqlalchemy.exc.ArgumentError: Could not determine join condition between parent/ child tables on relationship Line.next_lines. Specify a 'primaryjoin' expressio n. If 'secondary' is present, 'secondaryjoin' is needed as well.

Do you know how I could remedy this?

like image 511
mike Avatar asked Nov 14 '10 11:11

mike


People also ask

How do you create a many to many relationship in SQLAlchemy?

You add a tags class variable to the Post model. You use the db. relationship() method, passing it the name of the tags model ( Tag in this case). You pass the post_tag association table to the secondary parameter to establish a many-to-many relationship between posts and tags.

What is Backref in SQLAlchemy?

The sqlalchemy backref is one of the type keywords and it passed as the separate argument parameters which has to be used in the ORM mapping objects. It mainly includes the event listener on the configuration attributes with both directions of the user datas through explicitly handling the database relationships.

What is aliased in SQLAlchemy?

Aliases allow any table or subquery to be referenced by a unique name. In case of a table, this allows the same table to be named in the FROM clause multiple times. It provides a parent name for the columns represented by the statement, allowing them to be referenced relative to this name.

What is Backpopulate in SQLAlchemy?

The back_populates argument tells SqlAlchemy which column to link with when it joins the two tables. It allows you to access the linked records as a list with something like Parent.


1 Answers

You should just need:

prev_lines = relationship(
    Association,
    backref="next_lines",
    primaryjoin=id==Association.prev_id)

Since this specifies the next_lines back reference there is no need to have a next_lines relationship.

You can also do this using the remote_side parameter to a relationship: http://www.sqlalchemy.org/trac/browser/examples/adjacency_list/adjacency_list.py

like image 189
Nathan Villaescusa Avatar answered Sep 20 '22 01:09

Nathan Villaescusa