在SQLAlchemy中查询多对多

时间:2014-04-07 02:48:37

标签: python-2.7 sqlalchemy

我有两个与第三个关系表相关的表。基本上,我有很多适合,可以使用任意数量的标签,我试图使用tagID查询标记为某个标签的拟合。

Tag.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访问适合的标签。但是,我不知道如何根据标签查询拟合。我尝试了解{I}时遇到过filter的许多价值。

1 个答案:

答案 0 :(得分:0)

在查询中添加以下行:

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