Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find out if a lazy relation isn't loaded yet, with SQLAlchemy?

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.

like image 871
Joril Avatar asked Nov 03 '08 14:11

Joril


People also ask

What is lazy loading in SQLAlchemy?

Lazy loading refers to objects are returned from a query without the related objects loaded at first. When the given collection or reference is first accessed on a particular object, an additional SELECT statement is emitted such that the requested collection is loaded.

Why is SQLAlchemy so slow?

At the ORM level, the speed issues are because creating objects in Python is slow, and the SQLAlchemy ORM applies a large amount of bookkeeping to these objects as it fetches them, which is necessary in order for it to fulfill its usage contract, including unit of work, identity map, eager loading, collections, etc.

What does First () do in SQLAlchemy?

first() applies a limit of one within the generated SQL, so that only one primary entity row is generated on the server side (note this may consist of multiple result rows if join-loaded collections are present). Calling Query. first() results in an execution of the underlying query.

What is aliased in SQLAlchemy?

The alias in SQL corresponds to a “renamed” version of a table or SELECT statement, which occurs anytime you say “SELECT * FROM table1 AS a”. The AS creates a new name for the table. Aliases allow any table or subquery to be referenced by a unique name.


3 Answers

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
like image 140
kolypto Avatar answered Sep 28 '22 02:09

kolypto


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

like image 34
Haes Avatar answered Sep 28 '22 03:09

Haes


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

>>> hasattr(X, 'children')
False
like image 27
foz Avatar answered Sep 28 '22 02:09

foz