返回具有所有外键的行

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)>]
"""

【讨论】:

感谢您抽出宝贵时间提供帮助!这对我来说已经足够了!

以上是关于返回具有所有外键的行的主要内容,如果未能解决你的问题,请参考以下文章

删除具有外键约束且无级联删除 SQL 的行

Laravel Eloquent 播种机计算每个外键的行数

如何为具有复合主键的表构建外键?

C# Entity Framework Code-First-如何仅使用该外键的 id 添加带有外键的行?

mysql外键

HIbernate 无法删除具有外键的实体。外键设置为空