Question

I have two two tables that are related with a third relationship table. Basically, I have many fits, which can use any number of tags, and I'm trying to query the fits tagged with a certain tag using the 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 (stripped down)

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"),
                     })

And here's the function that I am trying to use:

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

I can access the tags of a fit via Fit._tags. However, I am not sure how to query for the fits based on tag. I've tried many values for filter that I've come across while trying to figure it out.

Was it helpful?

Solution

Add following line to your query:

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

Also, why such a strange name (_Fit__tags) for a relationship? I guess it is coming from django. Since sqlalchemy does not give special meanings in those, you can name is just tags.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top