On Aug 19, 2014, at 11:12 AM, Ljós Berinn <0na...@gmail.com> wrote:
> I have defined two models in my Pyramid app which are referencing the > existing database: > > class Locations(Base): > __tablename__ = 'Location' > __table_args__ = {u'schema': 'Locations'} > > Unit_id = Column(ForeignKey(u'Structure.Definition.Ship_id', > ondelete=u'RESTRICT', onupdate=u'CASCADE'), primary_key=True, nullable=False) > Timestamp = Column(DateTime, primary_key=True, nullable=False) > Latitude = Column(Float) > Longitude = Column(Float) > > > class Definitions(Base): > __tablename__ = 'Definition' > __table_args__ = {u'schema': 'Structure'} > > Ship_id = Column(Integer, primary_key=True) > Name = Column(String(90)) > > loc = relationship("Locations", backref=backref('Definition')) > > And I am using this query: > > sub = DBSession.query(Location.Unit_id, > func.max(Location.Timestamp).label('latest_timestamp')).\ > filter(Location.Latitude != None, Location.Longitude != None).\ > group_by(Location.Unit_id).\ > subquery() > > res = DBSession.query(Definition).\ > join((sub, sub.c.Unit_id == Definition.Unit_id)).\ > all() > > As a result, I get 5 Definition objects (since there's 5 rows in that table) > and each of them has all possible Location records which is a bit overkill at > the moment since Location table has hundreds of thousands of rows. > What I would like to get as a result instead is only the last Location (by > timestamp) for each of Definition records. > > I tried to play around with aliased but for some reason there is no way to > get only the last timestamp for each of my Definition object. > > I ended up with query like this: > > sub = DBSession.query(Locations).\ > filter(Locations.Latitude != None, Locations.Longitude != None).\ > order_by(desc(Locations.Timestamp)).\ > limit(1).\ > subquery() > > localias = aliased(Locations, sub) > > q = DBSession.query(Definitions, localias).\ > join((localias, Definitions.loc)).\ > all() > > but now I get only one Definition object with its last timestamp which is > also not exactly the thing I need in the end... > > I'm a bit confused what am I doing wrong here, so any tip/help/suggestion is > extremely appreciated! Thanks a lot! these queries can be tricky but there's a form for the best way to do it, which is to get the identifier for the most recent Location using max(): max_loc_id = session.query(func.max(Locations.id).label('location_id'), Locations.unit_id).group_by(Locations.unit_id).subquery() session.query(Definitions, Locations).join(max_loc_id, max_loc_id.c.unit_id == Definitions.ship_id).join(Locations, and_(Locations.id == max_loc_id.c.location_id, Locations.unit_id == Definitions.ship_id)) -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.