如何在SqlAlchemy中级联删除多个表?
我有一个表格,这个表格里有几个相关的表格,我想要在删除时让它们一起删除。但是我遇到了一些问题,删除的范围太广了。下面的代码可以帮助说明这个问题。
class Map(Base):
....
#One to many relationship between the Map and Tile.
#Each Map is made up of many tiles
tiles = relationship('Tile', lazy='joined', backref='map',
cascade="all, delete")
class Tile(Base):
....
#Reference to Map class.
map_id = Column(Integer,
ForeignKey('maps.id'),
nullable=False)
#Reference to graphics for this tile
#This is a many to one relationship, each Graphic is used by many Tiles
graphics_id = Column(Integer,
ForeignKey("graphics.id"),
nullable=False)
graphics = relationship("Graphic", uselist=False)
class Graphic(Base):
....
#Nothing special here
问题是,当我删除地图类的时候,地图图形也被删除了,这不是我想要的。我猜这和级联删除有关。
我该怎么做才能让删除地图类的时候只删除瓷砖,而不删除图形呢?
2 个回答
0
你的代码(除非有些细节被省略)应该能按你预期的那样工作:
图形不应该被删除。从relationship可以看出,默认的cascade
参数是save-update, merge
,这意味着如果你删除一个Map
,不应该触发delete
。
为了测试,请创建一个例程,生成一个Map
、一个Tile
和一个Graphic
;然后删除这个Map
,检查一下Graphic
是否被删除——我不认为会发生这种情况。如果这个推测是正确的,那么你的Graphic
对象一定是因为其他某个relationship
被删除的。
我提到的是SA版本0.64,但我相信在早期版本中,默认配置也没有什么不同。
0
我通过把
graphics = relationship("Graphic", uselist=False)
改成
graphics = relationship("Graphic", uselist=False, lazy='joined',
backref=backref('tiles', cascade="all, delete, delete-orphan"))
让它正常运行了。
我不确定这是不是最完美的答案,但它确实有效。