【问题标题】:Querying many-to-many in SQL Alchemy在 SQL Alchemy 中查询多对多
【发布时间】:2014-04-07 13:37:55
【问题描述】:

我有两个与第三个关系表相关的两个表。基本上,我有很多适合,可以使用任意数量的标签,我正在尝试使用 tagID 查询带有特定标签的适合。

标签.py:

tags_table = Table("tags", saveddata_meta,
                            Column("tagID", Integer, primary_key = True),
                            Column("name", String, nullable = False, unique=True))

mapper(Tag, tags_table)

Fit.py(精简版)

fits_table = Table("fits", saveddata_meta,
                         Column("ID", Integer, primary_key = True),
                         Column("ownerID", ForeignKey("users.ID"), nullable = True, index = True),
                         Column("name", String, nullable = False),
                         Column("timestamp", Integer, nullable = False))

fit_tags = Table("fit_tags", saveddata_meta,
                            Column("fitID", Integer, ForeignKey("fits.ID"), primary_key = True),
                            Column("tagID", Integer, ForeignKey("tags.tagID"), primary_key = True))

mapper(Fit, fits_table,
       properties = {
                     "_Fit__tags" : relation(Tag, secondary=fit_tags, backref="fits"),
                     })

这是我正在尝试使用的功能:

def getFitsWithTag(tagID, ownerID=None, where=None, eager=None):
    """
    Get all the fits tag with tagID
    If no user is passed, do this for all users.
    """
    if isinstance(tagID, int):
        if ownerID is not None and not isinstance(ownerID, int):
            raise TypeError("OwnerID must be integer")

        filter = Tag.tagID == tagID

        if ownerID is not None:
            filter = and_(filter, Fit.ownerID == ownerID)

        filter = processWhere(filter, where)
        eager = processEager(eager)
        with sd_lock:
            fits = saveddata_session.query(Fit).options(*eager).filter(filter).all()
    else:
        raise TypeError("TagID must be integer")
    return fits

我可以通过Fit._tags 访问适合的标签。但是,我不确定如何根据标签查询适合度。我尝试了很多 filter 的值,我在试图弄清楚时遇到了这些值。

【问题讨论】:

    标签: python-2.7 sqlalchemy


    【解决方案1】:

    在您的查询中添加以下行:

    def getFitsWithTag(tagID, ownerID=None, where=None, eager=None):
        # ...
        fits = (saveddata_session.query(Fit)
                .join(fit_tags).filter(fit_tags.c.tagID == tagID) # @note: add me
                .options(*eager).filter(filter)
                ).all()
        # ...
        return fits
    

    另外,为什么要为一段关系取这样一个奇怪的名字(_Fit__tags)?我猜它来自django。由于 sqlalchemy 没有在其中赋予特殊含义,因此您可以命名为 tags

    【讨论】:

    • 今晚有时间我会试试这个解决方案。另外,我不确定这些名称背后的原因是什么。我进入这个项目的时间很晚,这只是使用的惯例 - 不确定它背后是否有原因,或者它是否只是原始开发人员的偏好。 =)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-24
    • 2013-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    • 1970-01-01
    相关资源
    最近更新 更多