Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between with_entities and load_only in SQLAlchemy?

Tags:

When querying my database, I only want to load specified columns. Creating a query with with_entities requires a reference to the model column attribute, while creating a query with load_only requires a string corresponding to the column name. I would prefer to use load_only because it is easier to create a dynamic query using strings. What is the difference between the two?

load_only documentation

with_entities documentation

like image 833
Luke LaFountaine Avatar asked Nov 09 '17 01:11

Luke LaFountaine


People also ask

What is the difference between SQLAlchemy core and ORM?

Choosing Between SQLAlchemy Core and ORM The two modes use slightly different syntax, but the biggest difference between Core and ORM is the view of data as schema or business objects. SQLAlchemy Core has a schema-centric view, which like traditional SQL is focused around tables, keys, and index structures.

What is the difference between flask SQLAlchemy and SQLAlchemy?

One of which is that Flask-SQLAlchemy has its own API. This adds complexity by having its different methods for ORM queries and models separate from the SQLAlchemy API. Another disadvantage is that Flask-SQLAlchemy makes using the database outside of a Flask context difficult.

What is Server_default in SQLAlchemy?

server_default is specifically the SQL text that one would specify in the "DEFAULT" section of a "CREATE TABLE" statement, and SQLAlchemy has no special expectations in this area, it accepts SQL text like any other non-expression portion where a string is sent.

What is _sa_instance_state in SQLAlchemy?

_sa_instance_state is a non-database-persisted value used by SQLAlchemy internally (it refers to the InstanceState for the instance.


1 Answers

There are a few differences. The most important one when discarding unwanted columns (as in the question) is that using load_only will still result in creation of an object (a Model instance), while using with_entities will just get you tuples with values of chosen columns.

>>> query = User.query >>> query.options(load_only('email', 'id')).all() [<User 1 using e-mail: [email protected]>, <User 2 using e-mail: [email protected]>] >>> query.with_entities(User.email, User.id).all() [('[email protected]', 1), ('[email protected]', 2)]   

load_only

load_only() defers loading of particular columns from your models. It removes columns from query. You can still access all the other columns later, but an additional query (in the background) will be performed just when you try to access them.

"Load only" is useful when you store things like pictures of users in your database but you do not want to waste time transferring the images when not needed. For example, when displaying a list of users this might suffice:

User.query.options(load_only('name', 'fullname')) 

with_entities

with_entities() can either add or remove (simply: replace) models or columns; you can even use it to modify the query, to replace selected entities with your own function like func.count():

query = User.query count_query = query.with_entities(func.count(User.id))) count = count_query.scalar() 

Note that the resulting query is not the same as of query.count(), which would probably be slower - at least in MySQL (as it generates a subquery).

Another example of the extra capabilities of with_entities would be:

query = (     Page.query     .filter(<a lot of page filters>)     .join(Author).filter(<some author filters>) ) pages = query.all()  # ok, I got the pages. Wait, what? I want the authors too! # how to do it without generating the query again?  pages_and_authors = query.with_entities(Page, Author).all() 
like image 167
krassowski Avatar answered Nov 04 '22 05:11

krassowski