Thanks for quick reply Michael!
I will try to play with query you provided in a minute, but just to ask, I 
was reading about this 'eager loading' stuff... Is that maybe the thing I 
should use since this Location table is getting bigger and bigger every 
hour (10000+ or so rows) and I should optimize the query as much as 
possible... Also, there is a big chance that Definition table will also get 
extremely large and in one moment I will have to load all data from 
Definition and join it with last timestamp from Location...

Thank you one more time, will report about my progress :)


On Tuesday, August 19, 2014 4:19:13 PM UTC, Michael Bayer wrote:
>
>
> On Aug 19, 2014, at 11:12 AM, Ljós Berinn <0na...@gmail.com <javascript:>> 
> 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 
> <http://docs.sqlalchemy.org/en/latest/orm/tutorial.html#selecting-entities-from-subqueries>
>  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.

Reply via email to