如何创建SQLAlchemy嵌套过滤器
假设我在PostgreSQL中有一个照片标签的数据库结构。
这个结构很简单:
- 一个用户可以有很多照片
- 一张照片可以有很多标签
我正在使用SQLAlchemy,想要弄明白怎么写一个过滤器,来找到并删除特定用户所有照片的所有标签。
我知道怎么找到一个用户的所有照片:
specific_user_id = "1234"
DBSession = sessionmaker(bind=engine)
s = DBSession()
q = s.query(Photo).filter(Photo.user_id == specific_user_id)
q.delete()
我该怎么扩展这个方法来获取所有的标签呢?我可以使用循环:
for photo in q.all():
q2 = s.query(Tag).filter(Tag.photo_id == photo.photo_id)
q2.delete()
但我希望能不使用循环来完成这个任务。
1 个回答
1
假设这些模型大概是这样的:
class Photo(Base):
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey(User.id), nullable=False)
user = relationship(User, backref='photos')
class Tag(Base):
id = Column(Integer, primary_key=True)
photo_id = Column(Integer, ForeignKey(Photo.id), nullable=False)
photo = relationship(Photo, backref='tags')
每个模型都有一个外键指向它们的“拥有者”(用户或照片),并且与那个模型有关系。你可以通过在关系上写查询,来获取某个用户所有照片的标签。
tags = session.query(Tag).join(
Tag.photo, Photo.user
).filter(User.id == specific_user_id)
for tag in tags:
session.delete(tag)
session.commit()
使用 session.delete
而不是 query.delete
,因为这样可以让SQLAlchemy在后台进行清理,确保一切都符合你定义的其他关系规则。