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/strategies.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
@@ -16,8 +16,10 @@ import collections
import itertools
from typing import Any
from typing import Dict
from typing import Optional
from typing import Tuple
from typing import TYPE_CHECKING
from typing import Union
from . import attributes
from . import exc as orm_exc
@@ -45,7 +47,7 @@ from .interfaces import StrategizedProperty
from .session import _state_session
from .state import InstanceState
from .strategy_options import Load
from .util import _none_set
from .util import _none_only_set
from .util import AliasedClass
from .. import event
from .. import exc as sa_exc
@@ -57,8 +59,10 @@ from ..sql import util as sql_util
from ..sql import visitors
from ..sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL
from ..sql.selectable import Select
from ..util.typing import Literal
if TYPE_CHECKING:
from .mapper import Mapper
from .relationships import RelationshipProperty
from ..sql.elements import ColumnElement
@@ -932,8 +936,15 @@ class LazyLoader(
elif LoaderCallableStatus.NEVER_SET in primary_key_identity:
return LoaderCallableStatus.NEVER_SET
if _none_set.issuperset(primary_key_identity):
return None
# test for None alone in primary_key_identity based on
# allow_partial_pks preference. PASSIVE_NO_RESULT and NEVER_SET
# have already been tested above
if not self.mapper.allow_partial_pks:
if _none_only_set.intersection(primary_key_identity):
return None
else:
if _none_only_set.issuperset(primary_key_identity):
return None
if (
self.key in state.dict
@@ -1373,12 +1384,16 @@ class ImmediateLoader(PostLoader):
adapter,
populators,
):
if not context.compile_state.compile_options._enable_eagerloads:
return
(
effective_path,
run_loader,
execution_options,
recursion_depth,
) = self._setup_for_recursion(context, path, loadopt, self.join_depth)
if not run_loader:
# this will not emit SQL and will only emit for a many-to-one
# "use get" load. the "_RELATED" part means it may return
@@ -1957,6 +1972,18 @@ class SubqueryLoader(PostLoader):
adapter,
populators,
):
if (
loadopt
and context.compile_state.statement is not None
and context.compile_state.statement.is_dml
):
util.warn_deprecated(
"The subqueryload loader option is not compatible with DML "
"statements such as INSERT, UPDATE. Only SELECT may be used."
"This warning will become an exception in a future release.",
"2.0",
)
if context.refresh_state:
return self._immediateload_create_row_processor(
context,
@@ -2122,6 +2149,17 @@ class JoinedLoader(AbstractRelationshipLoader):
if not compile_state.compile_options._enable_eagerloads:
return
elif (
loadopt
and compile_state.statement is not None
and compile_state.statement.is_dml
):
util.warn_deprecated(
"The joinedload loader option is not compatible with DML "
"statements such as INSERT, UPDATE. Only SELECT may be used."
"This warning will become an exception in a future release.",
"2.0",
)
elif self.uselist:
compile_state.multi_row_eager_loaders = True
@@ -2506,13 +2544,13 @@ class JoinedLoader(AbstractRelationshipLoader):
or query_entity.entity_zero.represents_outer_join
or (chained_from_outerjoin and isinstance(towrap, sql.Join)),
_left_memo=self.parent,
_right_memo=self.mapper,
_right_memo=path[self.mapper],
_extra_criteria=extra_join_criteria,
)
else:
# all other cases are innerjoin=='nested' approach
eagerjoin = self._splice_nested_inner_join(
path, towrap, clauses, onclause, extra_join_criteria
path, path[-2], towrap, clauses, onclause, extra_join_criteria
)
compile_state.eager_joins[query_entity_key] = eagerjoin
@@ -2546,93 +2584,177 @@ class JoinedLoader(AbstractRelationshipLoader):
)
def _splice_nested_inner_join(
self, path, join_obj, clauses, onclause, extra_criteria, splicing=False
self,
path,
entity_we_want_to_splice_onto,
join_obj,
clauses,
onclause,
extra_criteria,
entity_inside_join_structure: Union[
Mapper, None, Literal[False]
] = False,
detected_existing_path: Optional[path_registry.PathRegistry] = None,
):
# recursive fn to splice a nested join into an existing one.
# splicing=False means this is the outermost call, and it
# should return a value. splicing=<from object> is the recursive
# form, where it can return None to indicate the end of the recursion
# entity_inside_join_structure=False means this is the outermost call,
# and it should return a value. entity_inside_join_structure=<mapper>
# indicates we've descended into a join and are looking at a FROM
# clause representing this mapper; if this is not
# entity_we_want_to_splice_onto then return None to end the recursive
# branch
if splicing is False:
# first call is always handed a join object
# from the outside
assert entity_we_want_to_splice_onto is path[-2]
if entity_inside_join_structure is False:
assert isinstance(join_obj, orm_util._ORMJoin)
elif isinstance(join_obj, sql.selectable.FromGrouping):
if isinstance(join_obj, sql.selectable.FromGrouping):
# FromGrouping - continue descending into the structure
return self._splice_nested_inner_join(
path,
entity_we_want_to_splice_onto,
join_obj.element,
clauses,
onclause,
extra_criteria,
splicing,
entity_inside_join_structure,
)
elif not isinstance(join_obj, orm_util._ORMJoin):
if path[-2].isa(splicing):
return orm_util._ORMJoin(
join_obj,
clauses.aliased_insp,
onclause,
isouter=False,
_left_memo=splicing,
_right_memo=path[-1].mapper,
_extra_criteria=extra_criteria,
)
else:
return None
elif isinstance(join_obj, orm_util._ORMJoin):
# _ORMJoin - continue descending into the structure
target_join = self._splice_nested_inner_join(
path,
join_obj.right,
clauses,
onclause,
extra_criteria,
join_obj._right_memo,
)
if target_join is None:
right_splice = False
join_right_path = join_obj._right_memo
# see if right side of join is viable
target_join = self._splice_nested_inner_join(
path,
join_obj.left,
entity_we_want_to_splice_onto,
join_obj.right,
clauses,
onclause,
extra_criteria,
join_obj._left_memo,
entity_inside_join_structure=(
join_right_path[-1].mapper
if join_right_path is not None
else None
),
)
if target_join is None:
# should only return None when recursively called,
# e.g. splicing refers to a from obj
assert (
splicing is not False
), "assertion failed attempting to produce joined eager loads"
return None
else:
right_splice = True
if right_splice:
# for a right splice, attempt to flatten out
# a JOIN b JOIN c JOIN .. to avoid needless
# parenthesis nesting
if not join_obj.isouter and not target_join.isouter:
eagerjoin = join_obj._splice_into_center(target_join)
if target_join is not None:
# for a right splice, attempt to flatten out
# a JOIN b JOIN c JOIN .. to avoid needless
# parenthesis nesting
if not join_obj.isouter and not target_join.isouter:
eagerjoin = join_obj._splice_into_center(target_join)
else:
eagerjoin = orm_util._ORMJoin(
join_obj.left,
target_join,
join_obj.onclause,
isouter=join_obj.isouter,
_left_memo=join_obj._left_memo,
)
eagerjoin._target_adapter = target_join._target_adapter
return eagerjoin
else:
eagerjoin = orm_util._ORMJoin(
# see if left side of join is viable
target_join = self._splice_nested_inner_join(
path,
entity_we_want_to_splice_onto,
join_obj.left,
target_join,
join_obj.onclause,
isouter=join_obj.isouter,
_left_memo=join_obj._left_memo,
clauses,
onclause,
extra_criteria,
entity_inside_join_structure=join_obj._left_memo,
detected_existing_path=join_right_path,
)
else:
eagerjoin = orm_util._ORMJoin(
target_join,
join_obj.right,
join_obj.onclause,
isouter=join_obj.isouter,
_right_memo=join_obj._right_memo,
)
eagerjoin._target_adapter = target_join._target_adapter
return eagerjoin
if target_join is not None:
eagerjoin = orm_util._ORMJoin(
target_join,
join_obj.right,
join_obj.onclause,
isouter=join_obj.isouter,
_right_memo=join_obj._right_memo,
)
eagerjoin._target_adapter = target_join._target_adapter
return eagerjoin
# neither side viable, return None, or fail if this was the top
# most call
if entity_inside_join_structure is False:
assert (
False
), "assertion failed attempting to produce joined eager loads"
return None
# reached an endpoint (e.g. a table that's mapped, or an alias of that
# table). determine if we can use this endpoint to splice onto
# is this the entity we want to splice onto in the first place?
if not entity_we_want_to_splice_onto.isa(entity_inside_join_structure):
return None
# path check. if we know the path how this join endpoint got here,
# lets look at our path we are satisfying and see if we're in the
# wrong place. This is specifically for when our entity may
# appear more than once in the path, issue #11449
# updated in issue #11965.
if detected_existing_path and len(detected_existing_path) > 2:
# this assertion is currently based on how this call is made,
# where given a join_obj, the call will have these parameters as
# entity_inside_join_structure=join_obj._left_memo
# and entity_inside_join_structure=join_obj._right_memo.mapper
assert detected_existing_path[-3] is entity_inside_join_structure
# from that, see if the path we are targeting matches the
# "existing" path of this join all the way up to the midpoint
# of this join object (e.g. the relationship).
# if not, then this is not our target
#
# a test condition where this test is false looks like:
#
# desired splice: Node->kind->Kind
# path of desired splice: NodeGroup->nodes->Node->kind
# path we've located: NodeGroup->nodes->Node->common_node->Node
#
# above, because we want to splice kind->Kind onto
# NodeGroup->nodes->Node, this is not our path because it actually
# goes more steps than we want into self-referential
# ->common_node->Node
#
# a test condition where this test is true looks like:
#
# desired splice: B->c2s->C2
# path of desired splice: A->bs->B->c2s
# path we've located: A->bs->B->c1s->C1
#
# above, we want to splice c2s->C2 onto B, and the located path
# shows that the join ends with B->c1s->C1. so we will
# add another join onto that, which would create a "branch" that
# we might represent in a pseudopath as:
#
# B->c1s->C1
# ->c2s->C2
#
# i.e. A JOIN B ON <bs> JOIN C1 ON <c1s>
# JOIN C2 ON <c2s>
#
if detected_existing_path[0:-2] != path.path[0:-1]:
return None
return orm_util._ORMJoin(
join_obj,
clauses.aliased_insp,
onclause,
isouter=False,
_left_memo=entity_inside_join_structure,
_right_memo=path[path[-1].mapper],
_extra_criteria=extra_criteria,
)
def _create_eager_adapter(self, context, result, adapter, path, loadopt):
compile_state = context.compile_state
@@ -2681,6 +2803,10 @@ class JoinedLoader(AbstractRelationshipLoader):
adapter,
populators,
):
if not context.compile_state.compile_options._enable_eagerloads:
return
if not self.parent.class_manager[self.key].impl.supports_population:
raise sa_exc.InvalidRequestError(
"'%s' does not support object "
@@ -2960,6 +3086,9 @@ class SelectInLoader(PostLoader, util.MemoizedSlots):
if not run_loader:
return
if not context.compile_state.compile_options._enable_eagerloads:
return
if not self.parent.class_manager[self.key].impl.supports_population:
raise sa_exc.InvalidRequestError(
"'%s' does not support object "
@@ -3117,7 +3246,7 @@ class SelectInLoader(PostLoader, util.MemoizedSlots):
orig_query = context.compile_state.select_statement
# the actual statement that was requested is this one:
# context_query = context.query
# context_query = context.user_passed_query
#
# that's not the cached one, however. So while it is of the identical
# structure, if it has entities like AliasedInsp, which we get from
@@ -3141,11 +3270,11 @@ class SelectInLoader(PostLoader, util.MemoizedSlots):
effective_path = path[self.parent_property]
if orig_query is context.query:
if orig_query is context.user_passed_query:
new_options = orig_query._with_options
else:
cached_options = orig_query._with_options
uncached_options = context.query._with_options
uncached_options = context.user_passed_query._with_options
# propagate compile state options from the original query,
# updating their "extra_criteria" as necessary.