jbrown
jbrown

Reputation: 7986

How to eagerly load objects from SqlAlchemy queries?

I've tried setting several options on my query such as:

session.query(CatalogueEntry)\
        .options(eagerload_all())\
        .filter(CatalogueEntry.source_path.in_(paths)).all()

But I keep getting errors:

...
File "/venv/lib/python2.7/site-packages/sqlalchemy/orm/__init__.py", line 245, in eagerload_all
return joinedload_all(*args, **kwargs)
File "/venv/lib/python2.7/site-packages/sqlalchemy/orm/strategy_options.py", line 665, in joinedload_all
_UnboundLoad.joinedload, keys, True, kw)
File "/venv/lib/python2.7/site-packages/sqlalchemy/orm/strategy_options.py", line 315, in _from_keys
opt = meth(opt, all_tokens[-1], **kw)
IndexError: list index out of range

If I change this to:

session.query(CatalogueEntry)\
        .options(eagerload_all('*'))\
        .filter(CatalogueEntry.source_path.in_(paths)).all()

I get:

DetachedInstanceError: Instance <CatalogueEntry at 0x1026936d0> is not bound to a Session; attribute refresh operation cannot proceed

I want to detach my objects from the session and pass them back into client code that will only read the properties. Before I added options I was getting DetachedInstanceErrors.

How can I return fully hydrated objects from an sqlalchemy (0.9.4) query whose properties can be read by other parts of my code after the session is closed?

Upvotes: 1

Views: 4361

Answers (1)

Michael Robellard
Michael Robellard

Reputation: 2358

session.query(CatalogueEntry)\
        .options(joinedload('name_of_relationship_attribute'))\
        .filter(CatalogueEntry.source_path.in_(paths)).all()

There is also subqueryload

You can also set the default load method in the relationship definition with lazy='joined' or lazy = 'subquery'

see this url for reference http://docs.sqlalchemy.org/en/rel_0_9/orm/loading.html?highlight=joinedload#sqlalchemy.orm.joinedload_all

Upvotes: 4

Related Questions