Lostsoul
Lostsoul

Reputation: 26027

sqlalchemy query based on a previous date?

Sorry if this is a strange question, I've been going through the docs/tutorial on the sqlalchemy site but I can't figure out how to do this specific query.

I have a bunch of dates of activity on my site that continues until changed. I know I can query specific dates or ranges of dates but what if I query a date(which doesn't exist) can I get the previous match?

For example say I have june 25, and june 30, as two dates, I run a query for June 29. Is it possible to get the June 25th data with only one query? I just want the previous match of a date I enter.

Upvotes: 0

Views: 185

Answers (1)

van
van

Reputation: 77012

Below is probably a simplified version of your model, but hopefully the example will help you create your own query.

Assuming the model is defined as below, and that the [Activity.person_id, Activity.date] is unique (basically, only one activity per day is allowed), the query using a subquery, which returns tuples (Person, _last_ Activity):

# MODEL:
class Person(Base):
    __tablename__ = 'person'
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String)
    activities = relationship('Activity', backref="person")

class Activity(Base):
    __tablename__ = 'activity'
    id = Column(Integer, primary_key=True, autoincrement=True)
    person_id = Column(Integer, ForeignKey('person.id'))
    name = Column(String)
    date = Column(Date)


# BUILDING THE QUERY
def get_latest_activity_before_or_at(last_date):
    AT = Activity.__table__
    q = (select([AT.c.person_id, func.max(AT.c.date).label("max_date")],
                (AT.c.date <= last_date)
                ).
            group_by(AT.c.person_id)).alias("subq")
    #print q

    #qry = session.query(Person, q).outerjoin(q, q.c.person_id == Person.id)
    qry = (session.query(Person).outerjoin(q, q.c.person_id == Person.id).
            outerjoin(Activity, and_(Activity.person_id == Person.id, Activity.date == q.c.max_date)))
    qry = qry.add_entity(Activity)
    return qry.all()

# TESTING the query:
last_date = datetime.date(2012, 7, 3)
res = get_latest_activity_before_or_at(last_date)
for x in res:
    print x

Upvotes: 1

Related Questions