AsyncQuery
This class is an Async wrapper for sqlalchemy.sql.Select
.
Table of Contents
Usage
The AsyncQuery
class provides a set of helper methods for asynchronously executing the query.
Example of usage:
query = select(User)
async_query = AsyncQuery(query, User._session)
async_query = async_query.filter(name__like='%John%').sort('-created_at').limit(2)
users = await async_query.all()
>>> users
# [<User 1>, <User 2>]
To get the sqlalchemy.sql.Select
instance to use native SQLAlchemy methods
use the query
property:
query = select(User)
async_query = AsyncQuery(query, User._session)
async_query.query
# <sqlalchemy.sql.Select object at 0x7f7f7f7f7f7f7f7f>
Warning
If no session is provided, a NoSessionError
will be raised
when attempting to execute the query. You must either provide
a session by passing it in this constructor or by calling
the set_session
method.
In the constructor:
Calling the set_session
method:
API Reference
options
Applies the given list of mapper options.
Warning
Quoting from SQLAlchemy docs:
When including `joinedload()` in reference to a one-to-many or many-to-many collection, the `Result.unique()` method must be applied to the returned result, which will make the incoming rows unique by primary key that otherwise are multiplied out by the join. The ORM will raise an error if this is not present. This is not automatic in modern SQLAlchemy, as it changes the behavior of the result set to return fewer ORM objects than the statement would normally return in terms of number of rows. Therefore SQLAlchemy keeps the use of Result.unique() explicit, so there is no ambiguity that the returned objects are made unique on primary key.
To learn more about options, see
sqlalchemy.orm.Query.options
docs.Parameters:
args
: Mapper options.Returns:
AsyncQuery
: Async query instance for chaining.Example:
filter
Filters the query.
Creates the WHERE clause of the query.
Parameters:
criterion
: SQLAlchemy style filter expressions.filters
: Django-style filters.Returns:
AsyncQuery
: Async query instance for chaining.Example:
order_by
Applies one or more ORDER BY criteria to the query.
Parameters:
columns
: Column names or SQLAlchemy column expressions.Returns:
AsyncQuery
: Async query instance for chaining.Example:
sort
Synonym for
order_by()
.
offset
Applies an OFFSET clause to the query.
Parameters:
offset
: Number of rows to skip.Returns:
AsyncQuery
: Async query instance for chaining.Raises:
ValueError
: If offset is negative.Example:
skip
Synonym for
offset()
.
limit
Applies a LIMIT clause to the query.
Parameters:
limit
: Maximum number of rows to return.Returns:
AsyncQuery
: Async query instance for chaining.Raises:
ValueError
: If limit is negative.Example:
take
Synonym for
limit()
.
join
def join(
*paths: QueryableAttribute | tuple[QueryableAttribute, bool],
model: type[_T] | None = None
)
Joined eager loading using LEFT OUTER JOIN.
When a tuple is passed, the second element must be boolean. If it is
True
, the join isINNER JOIN
, otherwiseLEFT OUTER JOIN
.Parameters:
paths
: Relationship attributes to join.model
: If given, checks that each path belongs to this model.Returns:
AsyncQuery
: Async query instance for chaining.Example:
with_subquery
def with_subquery(
*paths: QueryableAttribute | tuple[QueryableAttribute, bool],
model: type[_T] | None = None
)
Subqueryload or Selectinload eager loading.
Emits a second
SELECT
statement (Subqueryload) for each relationship to be loaded, across all result objects at once.When a tuple is passed, the second element must be boolean. If it is
True
, the eager loading strategy isSELECT IN
(Selectinload), otherwiseSELECT JOIN
(Subqueryload).Warning
A query which makes use of
subqueryload()
in conjunction with a limiting modifier such asQuery.limit()
orQuery.offset()
should always includeQuery.order_by()
against unique column(s) such as the primary key, so that the additional queries emitted bysubqueryload()
include the same ordering as used by the parent query. Without it, there is a chance that the inner query could return the wrong rows, as specified in SQLAlchemy docs.Parameters:
paths
: Relationship attributes to load.model
: If given, checks that each path belongs to this model.Returns:
AsyncQuery
: Async query instance for chaining.Example:
with_schema
def with_schema(
schema: dict[InstrumentedAttribute, str | tuple[str, dict[InstrumentedAttribute, Any]] | dict]
)
Joined, subqueryload and selectinload eager loading.
Useful for complex cases where you need to load nested relationships in separate queries.
Parameters:
schema
: Dictionary defining the loading strategy.Returns:
AsyncQuery
: Async query instance for chaining.
execute
Executes the query.
Parameters:
params
: SQLAlchemy statement execution parameters.Returns:
sqlalchemy.engine.Result[Any]
: Result of the query.Example:
scalars
Returns a
sqlalchemy.engine.ScalarResult
object containing all rows.This is same as calling
(await self.execute()).scalars()
.Returns:
sqlalchemy.engine.ScalarResult
: Scalars.Example:
first
Fetches the first row or
None
if no results are found.This is same as calling
(await self.scalars()).first()
.Returns:
Self | None
: Instance for method chaining orNone
if no matches.Example:
one
Fetches one row or raises an exception if no results are found.
If multiple results are found, raises
MultipleResultsFound
.This is same as calling
(await self.scalars()).one()
.Returns:
Self
: Instance for method chaining.Raises:
NoResultFound
: If no row is found.MultipleResultsFound
: If multiple rows match.Example:
one_or_none
Fetches one row or
None
if no results are found.If multiple results are found, raises
MultipleResultsFound
.This is same as calling
(await self.scalars()).one_or_none()
.Returns:
Self | None
: Instance for method chaining orNone
.Raises:
MultipleResultsFound
: If multiple rows match.Example:
fetch_one
Synonym for
one()
.
fetch_one_or_none
Synonym for
one_or_none()
.
all
Fetches all rows.
This is same as calling
(await self.scalars()).all()
.Returns:
list[Self]
: List of instances.Example:
fetch_all
Synonym for
all()
.
to_list
Synonym for
all()
.
unique
Returns a
sqlalchemy.engine.ScalarResult
object containing all unique rows.This is same as calling
(await self.scalars()).unique()
.Returns:
sqlalchemy.engine.ScalarResult
: Scalars.Example:
unique_all
Fetches all unique rows.
This is same as calling
(await self.unique()).all()
.Returns:
list[Self]
: List of instances.Example:
unique_first
Fetches the first unique row or
None
if no results are found.This is same as calling
(await self.unique()).first()
.Returns:
Self | None
: Instance for method chaining orNone
.Example:
unique_one
Fetches one unique row or raises an exception if no results are found.
If multiple results are found, raises
MultipleResultsFound
.This is same as calling
(await self.unique()).one()
.Returns:
Self
: Instance for method chaining.Raises:
NoResultFound
: If no row is found.MultipleResultsFound
: If multiple rows match.Example:
unique_one_or_none
Fetches one unique row or
None
if no results are found.If multiple results are found, raises
MultipleResultsFound
.This is same as calling
(await self.unique()).one_or_none()
.Returns:
Self | None
: Instance for method chaining orNone
.Raises:
MultipleResultsFound
: If multiple rows match.Example:
Access the Native Query Object
The native SQLAlchemy query object can be accessed via the query
property.