1
0
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:
MoonTestUse1
2025-02-09 01:11:49 +06:00
parent ce52f8a23a
commit 0aa3ef8fc2
5827 changed files with 14316 additions and 1906434 deletions

View File

@@ -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: