[英]FastAPI SQLAlchemy delete Many-to-Many relation causes StaleDataError
从表中删除 ManyToMany 关系时出错。 我发现问题是由bills_dishes
表中的相同项目引起的,但我需要添加相同的项目。
因此,下面的代码适用于没有重复项的项目,例如:
bill_id | dish_id
1 | 1
1 | 2
楷模:
bills_dishes_association = Table(
"bills_dishes",
Base.metadata,
Column("bill_id", Integer, ForeignKey("bills.id")),
Column("dish_id", Integer, ForeignKey("dishes.id")),
)
class Waiter(Base):
"""Waiter model."""
__tablename__ = "waiters"
id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(50), nullable=False)
password = Column(String(6), nullable=False)
bills = relationship("Bill")
def __repr__(self):
return f"Waiter(id={self.id}, username={self.username})"
class Bill(Base):
"""Bill model."""
__tablename__ = "bills"
id = Column(Integer, primary_key=True, autoincrement=True)
waiter_id = Column(Integer, ForeignKey("waiters.id"), nullable=False)
table_number = Column(Integer, nullable=False)
amount = Column(Float, nullable=False)
tip_percent = Column(Integer)
tip_included = Column(Boolean, default=False, nullable=False)
time = Column(DateTime(timezone=True), server_default=func.now())
dishes = relationship(
"Dish", secondary=bills_dishes_association, back_populates="ordered"
)
def __repr__(self):
return f"Bill(id={self.id}, table_number={self.table_number}, amount={self.amount})"
class Dish(Base):
"""Dish model."""
__tablename__ = "dishes"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(100), nullable=False)
description = Column(String(1024), nullable=False)
image_url = Column(String(500), nullable=False)
cost = Column(Float)
ordered = relationship(
"Bill",
secondary=bills_dishes_association,
back_populates="dishes",
cascade="all, delete",
passive_deletes=True,
)
crud.py:
def delete_bill(db: Session, bill_id: int):
"""Delete a bill by id."""
db_bill = db.query(Bill).filter(Bill.id == bill_id).first()
db.delete(db_bill)
db.commit()
return db_bill
但它不适用于这种情况:
bill_id | dish_id
1 | 2
1 | 2
sqlalchemy.orm.exc.StaleDataError: DELETE statement on table 'bills_dishes' expected to delete 1 row(s); Only 2 were matched.
如何处理?
我认为您需要在Bill
中的dishes
关系上设置passive_deletes=True
并将ondelete="CASCADE"
添加到bills_dishes_association
中的两个外键。
尽管对于关键表,您最好将 bills_dishes 提升为更像bills_dishes
的东西,并将其提升为像bill_lines
这样的完整的BillLine
这样Bill
-- 1tomany -- BillLine
-- manyto1 -- Dish
并给它自己的 PK id:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.