19

With SQLAlchemy, is there a way to know beforehand whether a relation would be lazy-loaded?
For example, given a lazy parent->children relation and an instance X of "parent", I'd like to know if "X.children" is already loaded, without triggering the query.

Joril
  • 19,961
  • 13
  • 71
  • 88

3 Answers3

27

You can get a list of all unloaded properties (both relations and columns) from sqlalchemy.orm.attributes.instance_state(obj).unloaded.

See: Completing object with its relations and avoiding unnecessary queries in sqlalchemy

An easier way is to use inspect(), which gives the same results:

from sqlalchemy import inspect
from sqlalchemy.orm import lazyload

user = session.query(User).options(lazyload(User.articles)).first()
ins = inspect(user)

ins.unloaded  # <- set or properties that are not yet loaded
Community
  • 1
  • 1
kolypto
  • 31,774
  • 17
  • 105
  • 99
5

I think you could look at the child's __dict__ attribute dictionary to check if the data is already there or not.

Haes
  • 12,891
  • 11
  • 46
  • 50
3

Slightly neater than Haes answer (though it effectively does the same thing) is to use hasattr(), as in:

>>> hasattr(X, 'children')
False
foz
  • 3,121
  • 1
  • 27
  • 21
  • 3
    This doesn't work with current sqlalchemy. `hasattr(obj, field)` is not equivalent to `field in obj.__dict__`. – Björn Lindqvist Mar 10 '13 at 13:41
  • I've tested in SQLAlchemy 0.8 and this does work if the object is detached. However if it is attached then using hasattr triggers the lazy load of 'children', which probably isn't what you want. Instead in 0.8 we can use the inspect() call: `res = inspect(X)` `'children' in res.unloaded` - which works whether the object is attached or detached. – foz Mar 11 '13 at 12:04