如何创建SQLAlchemy嵌套过滤器

2 投票
1 回答
2852 浏览
提问于 2025-04-18 08:11

假设我在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在后台进行清理,确保一切都符合你定义的其他关系规则。

撰写回答