Flask - SQLAlchemy 多对多原因 sqlalchemy.orm.exc.FlushError

Jos*_*hua 4 python many-to-many sqlalchemy flask-sqlalchemy

class Show(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), unique=True, nullable=False)
    studio = db.relationship("ShowStudio", backref="show", cascade="delete")

class Studio(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), unique=True, nullable=False)
    show = db.relationship("ShowStudio", backref="studio", cascade="delete")

class ShowStudio(db.Model):
    show_id = db.Column(db.Integer, db.ForeignKey(Show.id, ondelete="CASCADE"), primary_key=True)
    studio_id = db.Column(db.Integer, db.ForeignKey(Studio.id, ondelete="CASCADE"), primary_key=True)

studio = Studio(name="asd")

db.session.add(studio)
s = Show(title="a", studio=[studio])
db.session.flush()

db.session.add(s)
db.session.commit()
Run Code Online (Sandbox Code Playgroud)

当我运行它时,它抛出

sqlalchemy.orm.exc.FlushError:尝试刷新作为集合“Studio.show”成员的类型的项目。需要类型的对象或多态子类。

我遵循这里的答案。我不明白是什么原因导致了错误。欢迎任何帮助。

Ilj*_*ilä 5

多对多关系和使用关联对象模式(这是多对多的变体)之间似乎有点混淆。鉴于您配置模型的方式Show.studio实际上是与 的一对多关系,因此它需要对象ShowStudio的集合,而不是:ShowStudioStudio

studio = Studio(name="asd")    
db.session.add(studio)

showstudio = ShowStudio(studio=studio)
# You've disabled save-update cascade, so you have to
# add the association object to the session manually!
db.session.add(showstudio)

s = Show(title="a", studio=[showstudio])
db.session.add(s)

db.session.commit()
Run Code Online (Sandbox Code Playgroud)

对于您最初的尝试,您需要定义多对多关系ShowStudio使用底层表ShowStudio作为辅助表:

class Show(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), unique=True, nullable=False)
    studio = db.relationship("Studio", secondary="show_studio",
                             back_populates="show")

class Studio(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), unique=True, nullable=False)
    show = db.relationship("Show", secondary="show_studio",
                           back_populates="studio")

class ShowStudio(db.Model):
    show_id = db.Column(db.Integer, db.ForeignKey(Show.id, ondelete="CASCADE"),
                        primary_key=True)
    studio_id = db.Column(db.Integer, db.ForeignKey(Studio.id, ondelete="CASCADE"),
                          primary_key=True)
Run Code Online (Sandbox Code Playgroud)

由于Flask-SQLAlchemy__tablename__中没有明确设置,因此会自动将其设置为show_studioShowStudio