【发布时间】:2019-04-14 14:50:28
【问题描述】:
我有 sqlalchemy 模型:
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, and_
from sqlalchemy.orm import sessionmaker, relationship
engine = create_engine('sqlite:///:memory:')
Session = sessionmaker(bind=engine)
Base = declarative_base()
class TopicToPizzaAssociation(Base):
__tablename__ = 'association'
pizza_id = Column(Integer, ForeignKey('pizza.id'), primary_key=True)
topic_id = Column(Integer, ForeignKey('topic.id'), primary_key=True)
topic = relationship("Topic")
pizza = relationship("Pizza")
class Pizza(Base):
__tablename__ = 'pizza'
id = Column(Integer, primary_key=True)
topics = relationship("TopicToPizzaAssociation")
def add_topics(self, topics):
used_topics = {t.topic.product for t in self.topics}
associations = []
for topic in topics:
if topic.product not in used_topics:
associations.append(TopicToPizzaAssociation(pizza=self, topic=topic))
used_topics.add(topic.product)
p1.topics.extend(associations)
class Topic(Base):
__tablename__ = 'topic'
id = Column(Integer, primary_key=True)
product = Column(String(), nullable=False)
我需要选择所有具有所需主题集的披萨对象:
t1 = Topic(product='t1')
t2 = Topic(product='t2')
t3 = Topic(product='t3')
session = Session()
session.add_all([t1, t2, t3])
p1 = Pizza()
p2 = Pizza()
p1.add_topics([t1, t2, t1])
p2.add_topics([t2, t3])
Base.metadata.create_all(engine)
session.add_all([p1, p2])
session.commit()
values = ['t1', 't2']
topics = session.query(Topic.id).filter(Topic.product.in_(values))
pizza = session.query(Pizza).filter(Pizza.topics.any(TopicToPizzaAssociation.topic_id.in_(
topics
))).all()
这将返回具有主题之一的所有披萨。如果我尝试将any 替换为all,它不起作用。
我发现可以使用 JOIN 和 COUNT 进行查询,但我无法构建 sqlalchemy 查询。任何可能的解决方案都适合我。
【问题讨论】:
-
您对模型结构的更改持开放态度,还是结构已设置且无法更改?
-
我可以改变结构。
-
您所说的“必需设置”是指您不想要只有给定配料的比萨饼,还是不给定的配料,可能还有其他一些配料。
-
我想要有给定配料的披萨,可能还有其他配料。
标签: python sqlalchemy many-to-many