返回具有所有外键的行
Posted
技术标签:
【中文标题】返回具有所有外键的行【英文标题】:Returning a row that has all foreign keys 【发布时间】:2020-07-24 20:23:12 【问题描述】:我正在使用 sqlalchemy,我有一个地方模型和一个过程模型。 Places和Procedures之间是多对多的关系,每个Places有多个Procedure,一个Procedure可以由多个Places完成。
目前我有一个简单的查询,以便我可以搜索所有具有单一程序的地方。
for place in session.query(Place).filter(Place.procedures.any(Procedure.name == searchProcedure)):
这可以正常工作,我的查询当前将返回具有所需搜索过程的所有地点。
我想更改它,以便我有多个搜索过程,并且我只返回具有所有查询的搜索过程的任何地方。
我有一个使用 for 循环运行多个过滤器的可行解决方案
placeResults = session.query(Place)
for searchProcedure in proceduresQuery:
placeResults = placeResults.filter(Place.procedures.any(Procedure.name == searchProcedure))
for place in placeResults:
#do desired work with found places here
有没有更好的方法来使用 sqlalchemy(或一般的 sql)来做到这一点?我相信可能存在涉及连接的更短/更快的解决方案,但我不确定。
谢谢!
【问题讨论】:
编辑问题以将示例数据和所需结果显示为文本表格。 【参考方案1】:至少,如果程序数量相对较少,您可以将and_
的要求放在您的.filter
中:
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
engine = sa.create_engine("sqlite:///:memory:", echo=True)
Base = declarative_base()
# association table
place_procedure = sa.Table(
"place_procedure",
Base.metadata,
sa.Column("place_id", sa.ForeignKey("place.id"), primary_key=True),
sa.Column("procedure_id", sa.ForeignKey("procedure.id"), primary_key=True),
)
class Place(Base):
__tablename__ = "place"
id = sa.Column("id", sa.Integer, primary_key=True, autoincrement=False)
procedures = sa.orm.relationship(
"Procedure", secondary=place_procedure, back_populates="places"
)
def __init__(self, id, procedures):
self.id = id
self.procedures = procedures
def __repr__(self):
return f"<Place(id=self.id)>"
class Procedure(Base):
__tablename__ = "procedure"
id = sa.Column("id", sa.String(50), primary_key=True)
places = sa.orm.relationship(
"Place", secondary=place_procedure, back_populates="procedures"
)
def __init__(self, id):
self.id = id
def __repr__(self):
return f"<Procedure(id='self.id')>"
Base.metadata.create_all(engine)
Session = sa.orm.sessionmaker(bind=engine)
session = Session()
# test data
proc1 = Procedure("procedure1")
proc2 = Procedure("procedure2")
proc4 = Procedure("procedure4")
place0 = Place(0, [])
place1 = Place(1, [proc1])
place2 = Place(2, [proc2])
place3 = Place(3, [proc2, proc1])
place4 = Place(4, [proc4])
place5 = Place(5, [proc4, proc1])
place6 = Place(6, [proc4, proc2])
place7 = Place(7, [proc4, proc2, proc1])
session.add_all(
[
proc1,
proc2,
proc4,
place1,
place2,
place3,
place4,
place5,
place6,
place7,
]
)
session.commit
# test code
places_with_procedure1_and_procedure2 = (
session.query(Place)
.filter(
sa.and_(
Place.procedures.contains(proc1), Place.procedures.contains(proc2)
)
)
.all()
)
print(places_with_procedure1_and_procedure2)
"""console output:
[<Place(id=3)>, <Place(id=7)>]
"""
【讨论】:
感谢您抽出宝贵时间提供帮助!这对我来说已经足够了!以上是关于返回具有所有外键的行的主要内容,如果未能解决你的问题,请参考以下文章