简体   繁体   中英

How to properly define a many-to-many relationship in SQLAlchemy?

In my Flask application I am using SQLAlchemy , all tables are defined in one single file models.py :

training_ids_association_table = db.Table(
    "training_ids_association",
    db.Model.metadata,
    Column("training_id", Integer, ForeignKey("training_sessions.id")),
    Column("ids_id", Integer, ForeignKey("image_data_sets.id")),
)

class ImageDataSet(db.Model):
    __tablename__ = "image_data_sets"
    id = Column(Integer, primary_key=True)
    trainings = relationship("Training", secondary=training_ids_association_table, back_populates="image_data_sets")

class TrainingSession(db.Model):
    __tablename__ = "training_sessions"
    id = Column(Integer, primary_key=True)
    image_data_sets = relationship("DataSet", secondary=training_ids_association_table, back_populates="trainings")

So what I want to achieve here is a many-to-many relationship:

  • One ImageDataSet can belong to multiple TrainingSession 's
  • One TrainingSession can include multiple ImageDataSet 's

However, as soon as I call TrainingSession.query() in my code, the following error is raised:

Exception has occurred: InvalidRequestError
When initializing mapper mapped class ImageDataSet->image_data_sets, expression 'Training' failed to locate a name ('Training'). If this is a class name, consider adding this relationship() to the <class 'app.base.models.ImageDataSet'> class after both dependent classes have been defined.

I found some related threads here, but they are either asking for one-to-many relationships, or they define their tables in different files. Both is not the case here.

Any ideas what I am doing wrong?

You mispelled the names of the models, try this:

training_ids_association_table = db.Table(
    "training_ids_association",
    db.Model.metadata,
    Column("training_id", Integer, ForeignKey("training_sessions.id")),
    Column("ids_id", Integer, ForeignKey("image_data_sets.id")),
)

class ImageDataSet(db.Model):
    __tablename__ = "image_data_sets"
    id = Column(Integer, primary_key=True)
    trainings = relationship("TrainingSession", secondary=training_ids_association_table, back_populates="image_data_sets")

class TrainingSession(db.Model):
    __tablename__ = "training_sessions"
    id = Column(Integer, primary_key=True)
    image_data_sets = relationship("ImageDataSet", secondary=training_ids_association_table, back_populates="trainings")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM