Entity Framework (orm)¶
pydantic_linq.orm.DbContext ¶
DbContext(bind: Engine | AsyncEngine | Session | AsyncSession)
with DbContext(engine) as db: db.set(Hero).where(lambda h: h.age > 30).to_list().
Pass an AsyncEngine (or AsyncSession) and use async with and the *_async methods for async I/O.
As in EF, queries don't flush pending changes (no autoflush) and entities keep their values after save_changes.
begin_transaction ¶
begin_transaction() -> SessionTransaction
Database.BeginTransaction: call commit() or rollback() on the result, or use it in a with block.
ensure_created ¶
ensure_created() -> None
Database.EnsureCreated: create the tables of every SQLModel table model that don't exist yet.
ensure_deleted ¶
ensure_deleted() -> None
Database.EnsureDeleted: drop the tables of every SQLModel table model.
execute_sql ¶
execute_sql(sql: str, **params: Any) -> int
Database.ExecuteSql: run a statement; returns the affected row count.
find ¶
find(model: type[T], *key: Any) -> T | None
Find: by primary key; returns the tracked entity without a query when it is already loaded.
from_sql ¶
from_sql(model: type[T], sql: str, **params: Any) -> Queryable[T]
FromSql: a query over raw SQL that returns the model's columns. Bind values as :name params, never
by formatting them into the string. LINQ operators after it compose over it as a subquery.
update ¶
update(entity: object) -> None
Update: save the detached entity's current values on the next save_changes.
pydantic_linq.orm.Queryable ¶
Queryable(session: AnySession, model: type[T])
Bases: Enumerable[T]
A query against the database. Nothing runs until iteration or a terminal operator.
as_async_enumerable ¶
as_async_enumerable() -> AsyncEnumerable[T]
AsAsyncEnumerable: continue with the System.Linq.Async operators over the results.
as_enumerable ¶
as_enumerable() -> Enumerable[T]
AsEnumerable: later operators run in memory. The query runs on each enumeration.
as_no_tracking ¶
as_no_tracking() -> Queryable[T]
AsNoTracking: returned entities are detached, so changes to them aren't saved.
as_single_query ¶
as_single_query() -> Queryable[T]
AsSingleQuery: includes load through LEFT OUTER JOINs in the main query.
as_split_query ¶
as_split_query() -> Queryable[T]
AsSplitQuery: each include loads in its own SELECT ... IN query (the default here).
element_at_or_default_async
async
¶
element_at_or_default_async(index: int, default: T | None = None) -> T | None
execute_delete ¶
execute_delete() -> int
ExecuteDelete: one DELETE for the matching rows; returns the row count. Tracked entities aren't updated. The statement runs in the session's transaction, so save_changes() commits it.
execute_update ¶
execute_update(setters: Callable[[T], dict[Any, Any]]) -> int
ExecuteUpdate: execute_update(lambda h: {h.age: h.age + 1}) is one UPDATE; returns the row count.
first_or_default ¶
first_or_default(predicate: Callable[[T], Any] | None = None, default: T | None = None) -> T | None
first_or_default_async
async
¶
first_or_default_async(predicate: Callable[[T], Any] | None = None, default: T | None = None) -> T | None
for_each_async
async
¶
for_each_async(action: Callable[[T], Any]) -> None
ForEachAsync: action may be sync or async.
group_by ¶
group_by(key_selector: Callable[[T], K]) -> GroupedQueryable[K, T]
group_by(key_selector: Callable[[T], K], element_selector: Callable[[T], E]) -> GroupedQueryable[K, E]
group_by(key_selector: Callable[[T], K], element_selector: Callable[[T], E] | None = None, *, result_selector: Callable[[K, Enumerable[E]], R]) -> Queryable[R]
group_by(key_selector: Callable[[T], Any], element_selector: Callable[[T], Any] | None = None, *, result_selector: Callable[[Any, Enumerable[Any]], Any] | None = None) -> Any
GroupBy. Followed by select / where / order_by over g.key, g.count(), g.sum(...), ... it runs as
GROUP BY / HAVING. Enumerated directly, the groups are built in memory.
include ¶
include(navigation: Callable[[T], Any]) -> Queryable[T]
Include: eager-load a relationship (lambda h: h.team).
join ¶
join(inner: Iterable[I], outer_key_selector: Callable[[T], K], inner_key_selector: Callable[[I], K], result_selector: Callable[[T, I], R]) -> Queryable[R]
Join with another Queryable is an INNER JOIN.
last_or_default ¶
last_or_default(predicate: Callable[[T], Any] | None = None, default: T | None = None) -> T | None
last_or_default_async
async
¶
last_or_default_async(predicate: Callable[[T], Any] | None = None, default: T | None = None) -> T | None
left_join ¶
left_join(inner: Iterable[I], outer_key_selector: Callable[[T], K], inner_key_selector: Callable[[I], K], result_selector: Callable[[T, I | None], R]) -> Queryable[R]
LeftJoin (.NET 10 / EF 10): LEFT OUTER JOIN; unmatched rows pair with None.
order_by ¶
order_by(key_selector: Callable[[T], Any], comparer: Comparer | None = None) -> OrderedQueryable[T]
order_by_descending ¶
order_by_descending(key_selector: Callable[[T], Any], comparer: Comparer | None = None) -> OrderedQueryable[T]
right_join ¶
right_join(inner: Iterable[I], outer_key_selector: Callable[[T], K], inner_key_selector: Callable[[I], K], result_selector: Callable[[T | None, I], R]) -> Queryable[R]
RightJoin (.NET 10 / EF 10): run as the inner query LEFT JOIN this one.
select ¶
select(selector: Callable[[T], U]) -> Queryable[U]
Columns (lambda h: h.name, lambda h: (h.id, h.name)) are selected in SQL; anything else runs in memory.
select_many ¶
select_many(selector: Callable[[T], Iterable[U]]) -> Queryable[U]
select_many(selector: Callable[[T], Iterable[C]], result_selector: Callable[[T, C], U]) -> Queryable[U]
select_many(selector: Callable[[T], Iterable[Any]], result_selector: Callable[[T, Any], Any] | None = None) -> Queryable[Any]
SelectMany over a collection navigation (lambda t: t.heroes) is a JOIN; anything else runs in memory.
single_or_default ¶
single_or_default(predicate: Callable[[T], Any] | None = None, default: T | None = None) -> T | None
single_or_default_async
async
¶
single_or_default_async(predicate: Callable[[T], Any] | None = None, default: T | None = None) -> T | None
tag_with ¶
tag_with(tag: str) -> Queryable[T]
TagWith: put a comment into the SQL, to find the query in logs.
take ¶
take(count: int | slice) -> Queryable[T]
Take(int) or Take(Range); a range with negative bounds or a step runs in memory.
then_include ¶
then_include(navigation: Callable[[Any], Any]) -> Queryable[T]
ThenInclude: eager-load a relationship of the entity the previous include loaded.
to_dictionary_async
async
¶
to_dictionary_async(key_selector: Callable[[T], K], element_selector: Callable[[T], Any] | None = None) -> dict[K, Any]
pydantic_linq.orm.OrderedQueryable ¶
OrderedQueryable(session: AnySession, model: type[T])
Bases: Queryable[T], OrderedEnumerable[T]
IOrderedQueryable
pydantic_linq.orm.GroupedQueryable ¶
GroupedQueryable(query: Queryable[Any], key_selector: Callable[[Any], K], element_selector: Callable[[Any], Any] | None, having: tuple[Callable[[Any], Any], ...] = (), order: tuple[tuple[Callable[[Any], Any], bool, Comparer | None], ...] = ())
Bases: Enumerable[Grouping[K, T]]
Lambdas get g with g.key and the aggregates g.count(), g.sum(sel), g.min(sel), g.max(sel),
g.average(sel), g.any(). The same lambdas work on in-memory Grouping objects, so a select that can't be
translated (or plain enumeration) groups in memory instead.
count ¶
count(predicate: Callable[[Grouping[K, T]], Any] | None = None) -> int
The number of groups.
order_by ¶
order_by(key_selector: Callable[[Grouping[K, T]], Any], comparer: Comparer | None = None) -> OrderedGroupedQueryable[K, T]
order_by_descending ¶
order_by_descending(key_selector: Callable[[Grouping[K, T]], Any], comparer: Comparer | None = None) -> OrderedGroupedQueryable[K, T]
pydantic_linq.orm.SqlGrouping ¶
SqlGrouping(key: Any, element: Any)
What a lambda after group_by receives: g.key and SQL aggregates over the group's elements.