main commit
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-10-16 16:30:25 +09:00
parent 91c7e04474
commit 537e7b363f
1146 changed files with 45926 additions and 77196 deletions

View File

@@ -1,5 +1,5 @@
# orm/mapper.py
# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors
# Copyright (C) 2005-2023 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
@@ -132,9 +132,9 @@ _WithPolymorphicArg = Union[
]
_mapper_registries: weakref.WeakKeyDictionary[_RegistryType, bool] = (
weakref.WeakKeyDictionary()
)
_mapper_registries: weakref.WeakKeyDictionary[
_RegistryType, bool
] = weakref.WeakKeyDictionary()
def _all_registries() -> Set[registry]:
@@ -296,17 +296,6 @@ class Mapper(
particular primary key value. A "partial primary key" can occur if
one has mapped to an OUTER JOIN, for example.
The :paramref:`.orm.Mapper.allow_partial_pks` parameter also
indicates to the ORM relationship lazy loader, when loading a
many-to-one related object, if a composite primary key that has
partial NULL values should result in an attempt to load from the
database, or if a load attempt is not necessary.
.. versionadded:: 2.0.36 :paramref:`.orm.Mapper.allow_partial_pks`
is consulted by the relationship lazy loader strategy, such that
when set to False, a SELECT for a composite primary key that
has partial NULL values will not be emitted.
:param batch: Defaults to ``True``, indicating that save operations
of multiple entities can be batched together for efficiency.
Setting to False indicates
@@ -329,7 +318,7 @@ class Mapper(
class User(Base):
__table__ = user_table
__mapper_args__ = {"column_prefix": "_"}
__mapper_args__ = {'column_prefix':'_'}
The above mapping will assign the ``user_id``, ``user_name``, and
``password`` columns to attributes named ``_user_id``,
@@ -453,7 +442,7 @@ class Mapper(
mapping of the class to an alternate selectable, for loading
only.
.. seealso::
.. seealso::
:ref:`relationship_aliased_class` - the new pattern that removes
the need for the :paramref:`_orm.Mapper.non_primary` flag.
@@ -545,14 +534,14 @@ class Mapper(
base-most mapped :class:`.Table`::
class Employee(Base):
__tablename__ = "employee"
__tablename__ = 'employee'
id: Mapped[int] = mapped_column(primary_key=True)
discriminator: Mapped[str] = mapped_column(String(50))
__mapper_args__ = {
"polymorphic_on": discriminator,
"polymorphic_identity": "employee",
"polymorphic_on":discriminator,
"polymorphic_identity":"employee"
}
It may also be specified
@@ -561,18 +550,17 @@ class Mapper(
approach::
class Employee(Base):
__tablename__ = "employee"
__tablename__ = 'employee'
id: Mapped[int] = mapped_column(primary_key=True)
discriminator: Mapped[str] = mapped_column(String(50))
__mapper_args__ = {
"polymorphic_on": case(
"polymorphic_on":case(
(discriminator == "EN", "engineer"),
(discriminator == "MA", "manager"),
else_="employee",
),
"polymorphic_identity": "employee",
else_="employee"),
"polymorphic_identity":"employee"
}
It may also refer to any attribute using its string name,
@@ -580,14 +568,14 @@ class Mapper(
configurations::
class Employee(Base):
__tablename__ = "employee"
__tablename__ = 'employee'
id: Mapped[int] = mapped_column(primary_key=True)
discriminator: Mapped[str]
__mapper_args__ = {
"polymorphic_on": "discriminator",
"polymorphic_identity": "employee",
"polymorphic_identity": "employee"
}
When setting ``polymorphic_on`` to reference an
@@ -604,7 +592,6 @@ class Mapper(
from sqlalchemy import event
from sqlalchemy.orm import object_mapper
@event.listens_for(Employee, "init", propagate=True)
def set_identity(instance, *arg, **kw):
mapper = object_mapper(instance)
@@ -1056,7 +1043,7 @@ class Mapper(
"""
primary_key: Tuple[ColumnElement[Any], ...]
primary_key: Tuple[Column[Any], ...]
"""An iterable containing the collection of :class:`_schema.Column`
objects
which comprise the 'primary key' of the mapped table, from the
@@ -1619,11 +1606,9 @@ class Mapper(
if self._primary_key_argument:
coerced_pk_arg = [
(
self._str_arg_to_mapped_col("primary_key", c)
if isinstance(c, str)
else c
)
self._str_arg_to_mapped_col("primary_key", c)
if isinstance(c, str)
else c
for c in (
coercions.expect(
roles.DDLConstraintColumnRole,
@@ -2480,11 +2465,9 @@ class Mapper(
return "Mapper[%s%s(%s)]" % (
self.class_.__name__,
self.non_primary and " (non-primary)" or "",
(
self.local_table.description
if self.local_table is not None
else self.persist_selectable.description
),
self.local_table.description
if self.local_table is not None
else self.persist_selectable.description,
)
def _is_orphan(self, state: InstanceState[_O]) -> bool:
@@ -2554,7 +2537,7 @@ class Mapper(
if spec == "*":
mappers = list(self.self_and_descendants)
elif spec:
mapper_set: Set[Mapper[Any]] = set()
mapper_set = set()
for m in util.to_list(spec):
m = _class_to_mapper(m)
if not m.isa(self):
@@ -3261,9 +3244,14 @@ class Mapper(
The resulting structure is a dictionary of columns mapped
to lists of equivalent columns, e.g.::
{tablea.col1: {tableb.col1, tablec.col1}, tablea.col2: {tabled.col2}}
{
tablea.col1:
{tableb.col1, tablec.col1},
tablea.col2:
{tabled.col2}
}
""" # noqa: E501
"""
result: _EquivalentColumnMap = {}
def visit_binary(binary):
@@ -3428,11 +3416,9 @@ class Mapper(
return self.class_manager.mapper.base_mapper
def _result_has_identity_key(self, result, adapter=None):
pk_cols: Sequence[ColumnElement[Any]]
if adapter is not None:
pk_cols = [adapter.columns[c] for c in self.primary_key]
else:
pk_cols = self.primary_key
pk_cols: Sequence[ColumnClause[Any]] = self.primary_key
if adapter:
pk_cols = [adapter.columns[c] for c in pk_cols]
rk = result.keys()
for col in pk_cols:
if col not in rk:
@@ -3442,7 +3428,7 @@ class Mapper(
def identity_key_from_row(
self,
row: Union[Row[Any], RowMapping],
row: Optional[Union[Row[Any], RowMapping]],
identity_token: Optional[Any] = None,
adapter: Optional[ORMAdapter] = None,
) -> _IdentityKeyType[_O]:
@@ -3457,21 +3443,18 @@ class Mapper(
for the "row" argument
"""
pk_cols: Sequence[ColumnElement[Any]]
if adapter is not None:
pk_cols = [adapter.columns[c] for c in self.primary_key]
else:
pk_cols = self.primary_key
pk_cols: Sequence[ColumnClause[Any]] = self.primary_key
if adapter:
pk_cols = [adapter.columns[c] for c in pk_cols]
mapping: RowMapping
if hasattr(row, "_mapping"):
mapping = row._mapping
mapping = row._mapping # type: ignore
else:
mapping = row # type: ignore[assignment]
mapping = cast("Mapping[Any, Any]", row)
return (
self._identity_class,
tuple(mapping[column] for column in pk_cols),
tuple(mapping[column] for column in pk_cols), # type: ignore
identity_token,
)
@@ -3741,15 +3724,14 @@ class Mapper(
given::
class A: ...
class A:
...
class B(A):
__mapper_args__ = {"polymorphic_load": "selectin"}
class C(B): ...
class C(B):
...
class D(B):
__mapper_args__ = {"polymorphic_load": "selectin"}
@@ -3819,7 +3801,6 @@ class Mapper(
this subclass as a SELECT with IN.
"""
strategy_options = util.preloaded.orm_strategy_options
assert self.inherits
@@ -3843,7 +3824,7 @@ class Mapper(
classes_to_include.add(m)
m = m.inherits
for prop in self.column_attrs + self.relationships:
for prop in self.attrs:
# skip prop keys that are not instrumented on the mapped class.
# this is primarily the "_sa_polymorphic_on" property that gets
# created for an ad-hoc polymorphic_on SQL expression, issue #8704
@@ -4308,7 +4289,7 @@ def _dispose_registries(registries: Set[_RegistryType], cascade: bool) -> None:
reg._new_mappers = False
def reconstructor(fn: _Fn) -> _Fn:
def reconstructor(fn):
"""Decorate a method as the 'reconstructor' hook.
Designates a single method as the "reconstructor", an ``__init__``-like
@@ -4334,7 +4315,7 @@ def reconstructor(fn: _Fn) -> _Fn:
:meth:`.InstanceEvents.load`
"""
fn.__sa_reconstructor__ = True # type: ignore[attr-defined]
fn.__sa_reconstructor__ = True
return fn