mirror of
https://gitlab.com/MoonTestUse1/AdministrationItDepartmens.git
synced 2025-08-14 00:25:46 +02:00
Проверка 09.02.2025
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# orm/query.py
|
||||
# Copyright (C) 2005-2024 the SQLAlchemy authors and contributors
|
||||
# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors
|
||||
# <see AUTHORS file>
|
||||
#
|
||||
# This module is part of SQLAlchemy and is released under
|
||||
@@ -672,41 +672,38 @@ class Query(
|
||||
|
||||
from sqlalchemy.orm import aliased
|
||||
|
||||
|
||||
class Part(Base):
|
||||
__tablename__ = 'part'
|
||||
__tablename__ = "part"
|
||||
part = Column(String, primary_key=True)
|
||||
sub_part = Column(String, primary_key=True)
|
||||
quantity = Column(Integer)
|
||||
|
||||
included_parts = session.query(
|
||||
Part.sub_part,
|
||||
Part.part,
|
||||
Part.quantity).\
|
||||
filter(Part.part=="our part").\
|
||||
cte(name="included_parts", recursive=True)
|
||||
|
||||
included_parts = (
|
||||
session.query(Part.sub_part, Part.part, Part.quantity)
|
||||
.filter(Part.part == "our part")
|
||||
.cte(name="included_parts", recursive=True)
|
||||
)
|
||||
|
||||
incl_alias = aliased(included_parts, name="pr")
|
||||
parts_alias = aliased(Part, name="p")
|
||||
included_parts = included_parts.union_all(
|
||||
session.query(
|
||||
parts_alias.sub_part,
|
||||
parts_alias.part,
|
||||
parts_alias.quantity).\
|
||||
filter(parts_alias.part==incl_alias.c.sub_part)
|
||||
)
|
||||
parts_alias.sub_part, parts_alias.part, parts_alias.quantity
|
||||
).filter(parts_alias.part == incl_alias.c.sub_part)
|
||||
)
|
||||
|
||||
q = session.query(
|
||||
included_parts.c.sub_part,
|
||||
func.sum(included_parts.c.quantity).
|
||||
label('total_quantity')
|
||||
).\
|
||||
group_by(included_parts.c.sub_part)
|
||||
included_parts.c.sub_part,
|
||||
func.sum(included_parts.c.quantity).label("total_quantity"),
|
||||
).group_by(included_parts.c.sub_part)
|
||||
|
||||
.. seealso::
|
||||
|
||||
:meth:`_sql.Select.cte` - v2 equivalent method.
|
||||
|
||||
"""
|
||||
""" # noqa: E501
|
||||
return (
|
||||
self.enable_eagerloads(False)
|
||||
._get_select_statement_only()
|
||||
@@ -731,7 +728,7 @@ class Query(
|
||||
)
|
||||
|
||||
@overload
|
||||
def as_scalar(
|
||||
def as_scalar( # type: ignore[overload-overlap]
|
||||
self: Query[Tuple[_MAYBE_ENTITY]],
|
||||
) -> ScalarSelect[_MAYBE_ENTITY]: ...
|
||||
|
||||
@@ -941,9 +938,7 @@ class Query(
|
||||
:attr:`_query.Query.statement` using :meth:`.Session.execute`::
|
||||
|
||||
result = session.execute(
|
||||
query
|
||||
.set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL)
|
||||
.statement
|
||||
query.set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL).statement
|
||||
)
|
||||
|
||||
.. versionadded:: 1.4
|
||||
@@ -1052,8 +1047,7 @@ class Query(
|
||||
|
||||
some_object = session.query(VersionedFoo).get((5, 10))
|
||||
|
||||
some_object = session.query(VersionedFoo).get(
|
||||
{"id": 5, "version_id": 10})
|
||||
some_object = session.query(VersionedFoo).get({"id": 5, "version_id": 10})
|
||||
|
||||
:meth:`_query.Query.get` is special in that it provides direct
|
||||
access to the identity map of the owning :class:`.Session`.
|
||||
@@ -1119,7 +1113,7 @@ class Query(
|
||||
|
||||
:return: The object instance, or ``None``.
|
||||
|
||||
"""
|
||||
""" # noqa: E501
|
||||
self._no_criterion_assertion("get", order_by=False, distinct=False)
|
||||
|
||||
# we still implement _get_impl() so that baked query can override
|
||||
@@ -1563,19 +1557,22 @@ class Query(
|
||||
|
||||
# Users, filtered on some arbitrary criterion
|
||||
# and then ordered by related email address
|
||||
q = session.query(User).\
|
||||
join(User.address).\
|
||||
filter(User.name.like('%ed%')).\
|
||||
order_by(Address.email)
|
||||
q = (
|
||||
session.query(User)
|
||||
.join(User.address)
|
||||
.filter(User.name.like("%ed%"))
|
||||
.order_by(Address.email)
|
||||
)
|
||||
|
||||
# given *only* User.id==5, Address.email, and 'q', what
|
||||
# would the *next* User in the result be ?
|
||||
subq = q.with_entities(Address.email).\
|
||||
order_by(None).\
|
||||
filter(User.id==5).\
|
||||
subquery()
|
||||
q = q.join((subq, subq.c.email < Address.email)).\
|
||||
limit(1)
|
||||
subq = (
|
||||
q.with_entities(Address.email)
|
||||
.order_by(None)
|
||||
.filter(User.id == 5)
|
||||
.subquery()
|
||||
)
|
||||
q = q.join((subq, subq.c.email < Address.email)).limit(1)
|
||||
|
||||
.. seealso::
|
||||
|
||||
@@ -1671,9 +1668,11 @@ class Query(
|
||||
def filter_something(criterion):
|
||||
def transform(q):
|
||||
return q.filter(criterion)
|
||||
|
||||
return transform
|
||||
|
||||
q = q.with_transformation(filter_something(x==5))
|
||||
|
||||
q = q.with_transformation(filter_something(x == 5))
|
||||
|
||||
This allows ad-hoc recipes to be created for :class:`_query.Query`
|
||||
objects.
|
||||
@@ -1710,6 +1709,7 @@ class Query(
|
||||
schema_translate_map: Optional[SchemaTranslateMapType] = ...,
|
||||
populate_existing: bool = False,
|
||||
autoflush: bool = False,
|
||||
preserve_rowcount: bool = False,
|
||||
**opt: Any,
|
||||
) -> Self: ...
|
||||
|
||||
@@ -1789,9 +1789,15 @@ class Query(
|
||||
|
||||
E.g.::
|
||||
|
||||
q = sess.query(User).populate_existing().with_for_update(nowait=True, of=User)
|
||||
q = (
|
||||
sess.query(User)
|
||||
.populate_existing()
|
||||
.with_for_update(nowait=True, of=User)
|
||||
)
|
||||
|
||||
The above query on a PostgreSQL backend will render like::
|
||||
The above query on a PostgreSQL backend will render like:
|
||||
|
||||
.. sourcecode:: sql
|
||||
|
||||
SELECT users.id AS users_id FROM users FOR UPDATE OF users NOWAIT
|
||||
|
||||
@@ -1869,14 +1875,13 @@ class Query(
|
||||
|
||||
e.g.::
|
||||
|
||||
session.query(MyClass).filter(MyClass.name == 'some name')
|
||||
session.query(MyClass).filter(MyClass.name == "some name")
|
||||
|
||||
Multiple criteria may be specified as comma separated; the effect
|
||||
is that they will be joined together using the :func:`.and_`
|
||||
function::
|
||||
|
||||
session.query(MyClass).\
|
||||
filter(MyClass.name == 'some name', MyClass.id > 5)
|
||||
session.query(MyClass).filter(MyClass.name == "some name", MyClass.id > 5)
|
||||
|
||||
The criterion is any SQL expression object applicable to the
|
||||
WHERE clause of a select. String expressions are coerced
|
||||
@@ -1889,7 +1894,7 @@ class Query(
|
||||
|
||||
:meth:`_sql.Select.where` - v2 equivalent method.
|
||||
|
||||
"""
|
||||
""" # noqa: E501
|
||||
for crit in list(criterion):
|
||||
crit = coercions.expect(
|
||||
roles.WhereHavingRole, crit, apply_propagate_attrs=self
|
||||
@@ -1957,14 +1962,13 @@ class Query(
|
||||
|
||||
e.g.::
|
||||
|
||||
session.query(MyClass).filter_by(name = 'some name')
|
||||
session.query(MyClass).filter_by(name="some name")
|
||||
|
||||
Multiple criteria may be specified as comma separated; the effect
|
||||
is that they will be joined together using the :func:`.and_`
|
||||
function::
|
||||
|
||||
session.query(MyClass).\
|
||||
filter_by(name = 'some name', id = 5)
|
||||
session.query(MyClass).filter_by(name="some name", id=5)
|
||||
|
||||
The keyword expressions are extracted from the primary
|
||||
entity of the query, or the last entity that was the
|
||||
@@ -2091,10 +2095,12 @@ class Query(
|
||||
HAVING criterion makes it possible to use filters on aggregate
|
||||
functions like COUNT, SUM, AVG, MAX, and MIN, eg.::
|
||||
|
||||
q = session.query(User.id).\
|
||||
join(User.addresses).\
|
||||
group_by(User.id).\
|
||||
having(func.count(Address.id) > 2)
|
||||
q = (
|
||||
session.query(User.id)
|
||||
.join(User.addresses)
|
||||
.group_by(User.id)
|
||||
.having(func.count(Address.id) > 2)
|
||||
)
|
||||
|
||||
.. seealso::
|
||||
|
||||
@@ -2118,8 +2124,8 @@ class Query(
|
||||
|
||||
e.g.::
|
||||
|
||||
q1 = sess.query(SomeClass).filter(SomeClass.foo=='bar')
|
||||
q2 = sess.query(SomeClass).filter(SomeClass.bar=='foo')
|
||||
q1 = sess.query(SomeClass).filter(SomeClass.foo == "bar")
|
||||
q2 = sess.query(SomeClass).filter(SomeClass.bar == "foo")
|
||||
|
||||
q3 = q1.union(q2)
|
||||
|
||||
@@ -2128,7 +2134,9 @@ class Query(
|
||||
|
||||
x.union(y).union(z).all()
|
||||
|
||||
will nest on each ``union()``, and produces::
|
||||
will nest on each ``union()``, and produces:
|
||||
|
||||
.. sourcecode:: sql
|
||||
|
||||
SELECT * FROM (SELECT * FROM (SELECT * FROM X UNION
|
||||
SELECT * FROM y) UNION SELECT * FROM Z)
|
||||
@@ -2137,7 +2145,9 @@ class Query(
|
||||
|
||||
x.union(y, z).all()
|
||||
|
||||
produces::
|
||||
produces:
|
||||
|
||||
.. sourcecode:: sql
|
||||
|
||||
SELECT * FROM (SELECT * FROM X UNION SELECT * FROM y UNION
|
||||
SELECT * FROM Z)
|
||||
@@ -2249,7 +2259,9 @@ class Query(
|
||||
q = session.query(User).join(User.addresses)
|
||||
|
||||
Where above, the call to :meth:`_query.Query.join` along
|
||||
``User.addresses`` will result in SQL approximately equivalent to::
|
||||
``User.addresses`` will result in SQL approximately equivalent to:
|
||||
|
||||
.. sourcecode:: sql
|
||||
|
||||
SELECT user.id, user.name
|
||||
FROM user JOIN address ON user.id = address.user_id
|
||||
@@ -2262,10 +2274,12 @@ class Query(
|
||||
calls may be used. The relationship-bound attribute implies both
|
||||
the left and right side of the join at once::
|
||||
|
||||
q = session.query(User).\
|
||||
join(User.orders).\
|
||||
join(Order.items).\
|
||||
join(Item.keywords)
|
||||
q = (
|
||||
session.query(User)
|
||||
.join(User.orders)
|
||||
.join(Order.items)
|
||||
.join(Item.keywords)
|
||||
)
|
||||
|
||||
.. note:: as seen in the above example, **the order in which each
|
||||
call to the join() method occurs is important**. Query would not,
|
||||
@@ -2304,7 +2318,7 @@ class Query(
|
||||
as the ON clause to be passed explicitly. A example that includes
|
||||
a SQL expression as the ON clause is as follows::
|
||||
|
||||
q = session.query(User).join(Address, User.id==Address.user_id)
|
||||
q = session.query(User).join(Address, User.id == Address.user_id)
|
||||
|
||||
The above form may also use a relationship-bound attribute as the
|
||||
ON clause as well::
|
||||
@@ -2319,11 +2333,13 @@ class Query(
|
||||
a1 = aliased(Address)
|
||||
a2 = aliased(Address)
|
||||
|
||||
q = session.query(User).\
|
||||
join(a1, User.addresses).\
|
||||
join(a2, User.addresses).\
|
||||
filter(a1.email_address=='ed@foo.com').\
|
||||
filter(a2.email_address=='ed@bar.com')
|
||||
q = (
|
||||
session.query(User)
|
||||
.join(a1, User.addresses)
|
||||
.join(a2, User.addresses)
|
||||
.filter(a1.email_address == "ed@foo.com")
|
||||
.filter(a2.email_address == "ed@bar.com")
|
||||
)
|
||||
|
||||
The relationship-bound calling form can also specify a target entity
|
||||
using the :meth:`_orm.PropComparator.of_type` method; a query
|
||||
@@ -2332,11 +2348,13 @@ class Query(
|
||||
a1 = aliased(Address)
|
||||
a2 = aliased(Address)
|
||||
|
||||
q = session.query(User).\
|
||||
join(User.addresses.of_type(a1)).\
|
||||
join(User.addresses.of_type(a2)).\
|
||||
filter(a1.email_address == 'ed@foo.com').\
|
||||
filter(a2.email_address == 'ed@bar.com')
|
||||
q = (
|
||||
session.query(User)
|
||||
.join(User.addresses.of_type(a1))
|
||||
.join(User.addresses.of_type(a2))
|
||||
.filter(a1.email_address == "ed@foo.com")
|
||||
.filter(a2.email_address == "ed@bar.com")
|
||||
)
|
||||
|
||||
**Augmenting Built-in ON Clauses**
|
||||
|
||||
@@ -2347,7 +2365,7 @@ class Query(
|
||||
with the default criteria using AND::
|
||||
|
||||
q = session.query(User).join(
|
||||
User.addresses.and_(Address.email_address != 'foo@bar.com')
|
||||
User.addresses.and_(Address.email_address != "foo@bar.com")
|
||||
)
|
||||
|
||||
.. versionadded:: 1.4
|
||||
@@ -2360,29 +2378,28 @@ class Query(
|
||||
appropriate ``.subquery()`` method in order to make a subquery
|
||||
out of a query::
|
||||
|
||||
subq = session.query(Address).\
|
||||
filter(Address.email_address == 'ed@foo.com').\
|
||||
subquery()
|
||||
|
||||
|
||||
q = session.query(User).join(
|
||||
subq, User.id == subq.c.user_id
|
||||
subq = (
|
||||
session.query(Address)
|
||||
.filter(Address.email_address == "ed@foo.com")
|
||||
.subquery()
|
||||
)
|
||||
|
||||
|
||||
q = session.query(User).join(subq, User.id == subq.c.user_id)
|
||||
|
||||
Joining to a subquery in terms of a specific relationship and/or
|
||||
target entity may be achieved by linking the subquery to the
|
||||
entity using :func:`_orm.aliased`::
|
||||
|
||||
subq = session.query(Address).\
|
||||
filter(Address.email_address == 'ed@foo.com').\
|
||||
subquery()
|
||||
subq = (
|
||||
session.query(Address)
|
||||
.filter(Address.email_address == "ed@foo.com")
|
||||
.subquery()
|
||||
)
|
||||
|
||||
address_subq = aliased(Address, subq)
|
||||
|
||||
q = session.query(User).join(
|
||||
User.addresses.of_type(address_subq)
|
||||
)
|
||||
|
||||
q = session.query(User).join(User.addresses.of_type(address_subq))
|
||||
|
||||
**Controlling what to Join From**
|
||||
|
||||
@@ -2390,11 +2407,16 @@ class Query(
|
||||
:class:`_query.Query` is not in line with what we want to join from,
|
||||
the :meth:`_query.Query.select_from` method may be used::
|
||||
|
||||
q = session.query(Address).select_from(User).\
|
||||
join(User.addresses).\
|
||||
filter(User.name == 'ed')
|
||||
q = (
|
||||
session.query(Address)
|
||||
.select_from(User)
|
||||
.join(User.addresses)
|
||||
.filter(User.name == "ed")
|
||||
)
|
||||
|
||||
Which will produce SQL similar to::
|
||||
Which will produce SQL similar to:
|
||||
|
||||
.. sourcecode:: sql
|
||||
|
||||
SELECT address.* FROM user
|
||||
JOIN address ON user.id=address.user_id
|
||||
@@ -2498,11 +2520,16 @@ class Query(
|
||||
|
||||
A typical example::
|
||||
|
||||
q = session.query(Address).select_from(User).\
|
||||
join(User.addresses).\
|
||||
filter(User.name == 'ed')
|
||||
q = (
|
||||
session.query(Address)
|
||||
.select_from(User)
|
||||
.join(User.addresses)
|
||||
.filter(User.name == "ed")
|
||||
)
|
||||
|
||||
Which produces SQL equivalent to::
|
||||
Which produces SQL equivalent to:
|
||||
|
||||
.. sourcecode:: sql
|
||||
|
||||
SELECT address.* FROM user
|
||||
JOIN address ON user.id=address.user_id
|
||||
@@ -2865,7 +2892,7 @@ class Query(
|
||||
|
||||
Format is a list of dictionaries::
|
||||
|
||||
user_alias = aliased(User, name='user2')
|
||||
user_alias = aliased(User, name="user2")
|
||||
q = sess.query(User, User.id, user_alias)
|
||||
|
||||
# this expression:
|
||||
@@ -2874,26 +2901,26 @@ class Query(
|
||||
# would return:
|
||||
[
|
||||
{
|
||||
'name':'User',
|
||||
'type':User,
|
||||
'aliased':False,
|
||||
'expr':User,
|
||||
'entity': User
|
||||
"name": "User",
|
||||
"type": User,
|
||||
"aliased": False,
|
||||
"expr": User,
|
||||
"entity": User,
|
||||
},
|
||||
{
|
||||
'name':'id',
|
||||
'type':Integer(),
|
||||
'aliased':False,
|
||||
'expr':User.id,
|
||||
'entity': User
|
||||
"name": "id",
|
||||
"type": Integer(),
|
||||
"aliased": False,
|
||||
"expr": User.id,
|
||||
"entity": User,
|
||||
},
|
||||
{
|
||||
'name':'user2',
|
||||
'type':User,
|
||||
'aliased':True,
|
||||
'expr':user_alias,
|
||||
'entity': user_alias
|
||||
}
|
||||
"name": "user2",
|
||||
"type": User,
|
||||
"aliased": True,
|
||||
"expr": user_alias,
|
||||
"entity": user_alias,
|
||||
},
|
||||
]
|
||||
|
||||
.. seealso::
|
||||
@@ -2938,6 +2965,7 @@ class Query(
|
||||
context = QueryContext(
|
||||
compile_state,
|
||||
compile_state.statement,
|
||||
compile_state.statement,
|
||||
self._params,
|
||||
self.session,
|
||||
self.load_options,
|
||||
@@ -3001,10 +3029,12 @@ class Query(
|
||||
|
||||
e.g.::
|
||||
|
||||
q = session.query(User).filter(User.name == 'fred')
|
||||
q = session.query(User).filter(User.name == "fred")
|
||||
session.query(q.exists())
|
||||
|
||||
Producing SQL similar to::
|
||||
Producing SQL similar to:
|
||||
|
||||
.. sourcecode:: sql
|
||||
|
||||
SELECT EXISTS (
|
||||
SELECT 1 FROM users WHERE users.name = :name_1
|
||||
@@ -3053,7 +3083,9 @@ class Query(
|
||||
r"""Return a count of rows this the SQL formed by this :class:`Query`
|
||||
would return.
|
||||
|
||||
This generates the SQL for this Query as follows::
|
||||
This generates the SQL for this Query as follows:
|
||||
|
||||
.. sourcecode:: sql
|
||||
|
||||
SELECT count(1) AS count_1 FROM (
|
||||
SELECT <rest of query follows...>
|
||||
@@ -3093,8 +3125,7 @@ class Query(
|
||||
|
||||
# return count of user "id" grouped
|
||||
# by "name"
|
||||
session.query(func.count(User.id)).\
|
||||
group_by(User.name)
|
||||
session.query(func.count(User.id)).group_by(User.name)
|
||||
|
||||
from sqlalchemy import distinct
|
||||
|
||||
@@ -3112,7 +3143,9 @@ class Query(
|
||||
)
|
||||
|
||||
def delete(
|
||||
self, synchronize_session: SynchronizeSessionArgument = "auto"
|
||||
self,
|
||||
synchronize_session: SynchronizeSessionArgument = "auto",
|
||||
delete_args: Optional[Dict[Any, Any]] = None,
|
||||
) -> int:
|
||||
r"""Perform a DELETE with an arbitrary WHERE clause.
|
||||
|
||||
@@ -3120,11 +3153,11 @@ class Query(
|
||||
|
||||
E.g.::
|
||||
|
||||
sess.query(User).filter(User.age == 25).\
|
||||
delete(synchronize_session=False)
|
||||
sess.query(User).filter(User.age == 25).delete(synchronize_session=False)
|
||||
|
||||
sess.query(User).filter(User.age == 25).\
|
||||
delete(synchronize_session='evaluate')
|
||||
sess.query(User).filter(User.age == 25).delete(
|
||||
synchronize_session="evaluate"
|
||||
)
|
||||
|
||||
.. warning::
|
||||
|
||||
@@ -3137,6 +3170,13 @@ class Query(
|
||||
:ref:`orm_expression_update_delete` for a discussion of these
|
||||
strategies.
|
||||
|
||||
:param delete_args: Optional dictionary, if present will be passed
|
||||
to the underlying :func:`_expression.delete` construct as the ``**kw``
|
||||
for the object. May be used to pass dialect-specific arguments such
|
||||
as ``mysql_limit``.
|
||||
|
||||
.. versionadded:: 2.0.37
|
||||
|
||||
:return: the count of rows matched as returned by the database's
|
||||
"row count" feature.
|
||||
|
||||
@@ -3144,9 +3184,9 @@ class Query(
|
||||
|
||||
:ref:`orm_expression_update_delete`
|
||||
|
||||
"""
|
||||
""" # noqa: E501
|
||||
|
||||
bulk_del = BulkDelete(self)
|
||||
bulk_del = BulkDelete(self, delete_args)
|
||||
if self.dispatch.before_compile_delete:
|
||||
for fn in self.dispatch.before_compile_delete:
|
||||
new_query = fn(bulk_del.query, bulk_del)
|
||||
@@ -3156,6 +3196,10 @@ class Query(
|
||||
self = bulk_del.query
|
||||
|
||||
delete_ = sql.delete(*self._raw_columns) # type: ignore
|
||||
|
||||
if delete_args:
|
||||
delete_ = delete_.with_dialect_options(**delete_args)
|
||||
|
||||
delete_._where_criteria = self._where_criteria
|
||||
result: CursorResult[Any] = self.session.execute(
|
||||
delete_,
|
||||
@@ -3182,11 +3226,13 @@ class Query(
|
||||
|
||||
E.g.::
|
||||
|
||||
sess.query(User).filter(User.age == 25).\
|
||||
update({User.age: User.age - 10}, synchronize_session=False)
|
||||
sess.query(User).filter(User.age == 25).update(
|
||||
{User.age: User.age - 10}, synchronize_session=False
|
||||
)
|
||||
|
||||
sess.query(User).filter(User.age == 25).\
|
||||
update({"age": User.age - 10}, synchronize_session='evaluate')
|
||||
sess.query(User).filter(User.age == 25).update(
|
||||
{"age": User.age - 10}, synchronize_session="evaluate"
|
||||
)
|
||||
|
||||
.. warning::
|
||||
|
||||
@@ -3209,9 +3255,8 @@ class Query(
|
||||
strategies.
|
||||
|
||||
:param update_args: Optional dictionary, if present will be passed
|
||||
to the underlying :func:`_expression.update`
|
||||
construct as the ``**kw`` for
|
||||
the object. May be used to pass dialect-specific arguments such
|
||||
to the underlying :func:`_expression.update` construct as the ``**kw``
|
||||
for the object. May be used to pass dialect-specific arguments such
|
||||
as ``mysql_limit``, as well as other special arguments such as
|
||||
:paramref:`~sqlalchemy.sql.expression.update.preserve_parameter_order`.
|
||||
|
||||
@@ -3297,6 +3342,7 @@ class Query(
|
||||
context = QueryContext(
|
||||
compile_state,
|
||||
compile_state.statement,
|
||||
compile_state.statement,
|
||||
self._params,
|
||||
self.session,
|
||||
self.load_options,
|
||||
@@ -3385,6 +3431,14 @@ class BulkUpdate(BulkUD):
|
||||
class BulkDelete(BulkUD):
|
||||
"""BulkUD which handles DELETEs."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
query: Query[Any],
|
||||
delete_kwargs: Optional[Dict[Any, Any]],
|
||||
):
|
||||
super().__init__(query)
|
||||
self.delete_kwargs = delete_kwargs
|
||||
|
||||
|
||||
class RowReturningQuery(Query[Row[_TP]]):
|
||||
if TYPE_CHECKING:
|
||||
|
Reference in New Issue
Block a user