gpt4 book ai didi

python - Sqlalchemy:查询多态类的 m2m 关系

转载 作者:行者123 更新时间:2023-11-28 17:34:07 24 4
gpt4 key购买 nike

我有两个通过多对多关系连接的类:ParentTag

Base = declarative_base()

association_table = Table('associations', Base.metadata,
Column('parent_id', Integer, ForeignKey('parent.id')),
Column('tag_id', Integer, ForeignKey('tag.id')),
)

class Tag(Base):
__tablename__ = 'tags'
id = Column(Integer, Sequence('tag_id_seq'), primary_key=True)
name = Column(String)


class Parent(Base):
__tablename__ = 'parents'
id = Column(Integer, Sequence('parent_id_seq'), primary_key=True)
tags = relationship('Tag', secondary=association_table, backref='parents')

如果我想查询所有与 Parent 有一个或多个关系的 Tag 对象,我会这样做:

session.query(Tag).filter(Tag.parents.any()).all()

但是,这个Parent 类是子类AliceBob 的父类:

class Alice(Parent):
__tablename__ = 'alices'
__mapper_args__ = {'polymorphic_identity': 'alice'}
alice_id = Column(Integer, ForeignKey('parents.id'), primary_key=True)

class Bob(Parent):
__tablename__ = 'bobs'
__mapper_args__ = {'polymorphic_identity': 'bob'}
bob_id = Column(Integer, ForeignKey('parents.id'), primary_key=True)

现在我希望能够检索所有与 Alice 对象有一个或多个关系的 Tag 对象。先前的查询 session.query(Tag).filter(Tag.parents.any()).all() 不会执行,因为它不区分 AliceBob 对象 - 它甚至不知道它们的存在。

我已经弄乱了 Query 一段时间但没有成功,所以我假设如果它可以完成,它一定与 Table 类中的一些额外代码行有关,如上所示。虽然文档包含有关 polymorphic classes 的信息和 many-to-many relations迈克拜耳自己提供了一个人this回答一个看似相关的问题,这个问题看起来很有趣,但我远未理解,我有点卡住了。

这些代码示例可能会让 Python 解释器感到厌恶,但它确实能表达我的观点。糖果给那些能在路上帮助我的人!

最佳答案

在编写一些 MWE 时,我实际上找到了一个解决方案,它实际上与我已经尝试过的几乎相同。不过,budder 给了我新的希望,谢谢 :)

from sqlalchemy import create_engine, ForeignKey, Column, String, Integer, Sequence, Table
from sqlalchemy.orm import sessionmaker, relationship, backref
from sqlalchemy.ext.declarative import declarative_base


Base = declarative_base()

association_table = Table('associations', Base.metadata,
Column('parent_id', Integer, ForeignKey('parents.id')),
Column('tag_id', Integer, ForeignKey('tags.id')),
)


class Tag(Base):
__tablename__ = 'tags'
id = Column(Integer, Sequence('tag_id_seq'), primary_key=True)
name = Column(String)


class Parent(Base):
__tablename__ = 'parents'
id = Column(Integer, Sequence('parent_id_seq'), primary_key=True)
tags = relationship('Tag', secondary=association_table, backref='parents')


class Alice(Parent):
__tablename__ = 'alices'
__mapper_args__ = {'polymorphic_identity': 'alice'}
alice_id = Column(Integer, ForeignKey('parents.id'), primary_key=True)


class Bob(Parent):
__tablename__ = 'bobs'
__mapper_args__ = {'polymorphic_identity': 'bob'}
bob_id = Column(Integer, ForeignKey('parents.id'), primary_key=True)


engine = create_engine("sqlite://")
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

tag_a = Tag(name='a')
tag_b = Tag(name='b')
tag_c = Tag(name='c')
session.add(tag_a)
session.add(tag_b)
session.add(tag_c)
session.commit()
session.add(Alice(tags=[tag_a]))
session.add(Bob(tags=[tag_b]))
session.commit()

for tag in session.query(Tag).\
filter(Tag.parents.any(Parent.id == Alice.alice_id)).\
all():
print(tag.name)

如果有更好的替代方法,我仍然会感兴趣。我可以想象 sqlalchemy 提供了一种更直接、更优雅的方法,例如:

for tag in session.query(Tag).\
filter(Tag.alices.any()).\
all():
print(tag.name)

关于python - Sqlalchemy:查询多态类的 m2m 关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32108788/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com