Flask-SQLAlchemy Legacy vs New Query Interface

Question:

I am trying to update some queries in a web application because as stated in Flask-SQLAlchemy

You may see uses of Model.query or session.query to build queries. That query interface is
considered legacy in SQLAlchemy. Prefer using the session.execute(select(...)) instead.

I have a query:

subnets = db.session.query(Subnet).order_by(Subnet.id).all()

Which is translated into:

SELECT subnet.id AS subnet_id, subnet.name AS subnet_name, subnet.network AS subnet_network, subnet.access AS subnet_access, subnet.date_created AS subnet_date_created
FROM subnet ORDER BY subnet.id

And I take the subnets variable and loop it over in my view in two different locations. And it works.

However, when I try to update my query and use the new SQLAlchemy interface:

subnets = db.session.execute(db.select(Subnet).order_by(Subnet.id)).scalars()

I can only loop once and there is nothing left to loop over in the second loop?

How can I achieve the same result with the new query interface?

Asked By: Tes3awy

||

Answers:

As noted in the comments to the question, your second example is not directly comparable to your first example because your second example is missing the .all() at the end.

Side note:

session.scalars(select(Subnet).order_by(Subnet.id)).all()

is a convenient shorthand for

session.execute(select(Subnet).order_by(Subnet.id)).scalars().all()

and is the recommended approach for SQLAlchemy 1.4+.

Answered By: Gord Thompson

Check out the 2.0 migration docs for ORM:

https://docs.sqlalchemy.org/en/14/changelog/migration_20.html#migration-orm-usage

It lists some examples to show your how to migrate your code from 1.x style to 2.x style. For example:

get()

1.x:

session.query(User).get(42)

2.x:

session.get(User, 42)

all()

1.x:

session.query(User).all()

2.x:

session.execute(select(User)).scalars().all()

Note

For Flask-SQLAlchemy, you also need to:

  1. Replace session with db.session.
  2. Replace select with db.select or import the select directly from sqlalchemy:
from sqlalchemy import select
Answered By: Grey Li
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.