Python 删除具有多对多关系的行
我有两张桌子,Python 删除具有多对多关系的行,python,orm,sqlalchemy,Python,Orm,Sqlalchemy,我有两张桌子,image和restaurant。我在他们之间建立了一种多对多的关系 以下是表格定义的相关部分: images_assoc = Table('restaurant_image_assoc', Base.metadata, Column('restaurant', Integer(unsigned=True), ForeignKey('restaurant.id')), Column('image', Integer(unsig
image
和restaurant
。我在他们之间建立了一种多对多的关系
以下是表格定义的相关部分:
images_assoc = Table('restaurant_image_assoc', Base.metadata,
Column('restaurant', Integer(unsigned=True),
ForeignKey('restaurant.id')),
Column('image', Integer(unsigned=True),
ForeignKey('image.id')))
class Image(Base):
__tablename__ = 'image'
id = Column(Integer(unsigned=True), primary_key=True)
reports = Column(TinyInt, nullable=False, default=0)
created_at = Column(DateTime, default=datetime.now)
class Restaurant(Base):
__tablename__ = 'restaurant'
id = Column(Integer(unsigned=True), primary_key=True)
images = relationship(Image, secondary=images_assoc)
我需要删除image
中的一行,但当然我需要删除restaurant\u image\u assoc
中首先指向它的所有行。我该怎么做
我试过这个:
request.db.query(images_assoc)\
.filter(images_assoc.c.image==image.id).delete()
request.db.delete(image)
request.db.commit()
其中,image
是我要删除的行,但我得到以下错误:
AttributeError: 'Table' object has no attribute 'class_'
如果您删除图像中的一行,您应该获得该图像id。然后您可以在assoc表中删除,其中图像id==您的图像id。问题是SA没有从图像的侧面跟踪餐厅和图像之间的关系,因此它“不知道”存在依赖关系。从另一端配置关系后,关联表中的相应行也将自动删除。为了添加关系的另一面,只需使用
backref
:
class Restaurant(Base):
images = relationship(Image, secondary=images_assoc, backref="restaurants")
但您也可以在每个对象上明确定义这些对象(在这种情况下需要back\u populates
):
但后者在语义上与使用
backref
相同,我甚至不能这样做。我更新了我的帖子以展示我所做的尝试。您是否尝试过在image和image_assoc之间的关系上设置删除孤立级联?没有关系,当我试图建立关系时,它开始对我大喊大叫。我目前已经用原始SQL破解了一些东西。这里的具体错误消息是Query()现在不能处理这样的表(Query(images\u assoc)…delete())。不过,与其他答案一样,只要操纵Restaurant.images,就会自动处理images_assoc中的行-因为它是“次要的”,所以这与级联设置无关。也就是说,如果你说restaurant.images.remove(一些图像),然后flush,那么你只需要删除images\u assoc中的行。问题是当你有太多的对象时。SqlAlchemy抛出大量的delete from。在我们的例子中,每个对象最多有55000k行,我们有大约2k个对象。我们的postgres速度很快,但运行55k*2k=1.1亿次查询需要很长时间
class Image(Base):
restaurants = relationship("Restaurant", secondary=images_assoc, back_populates="images")
class Restaurant(Base):
images = relationship(Image, secondary=images_assoc, back_populates="restaurants")