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/properties.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
@@ -28,7 +28,6 @@ from typing import TypeVar
from typing import Union
from . import attributes
from . import exc as orm_exc
from . import strategy_options
from .base import _DeclarativeMapped
from .base import class_mapper
@@ -44,6 +43,7 @@ from .interfaces import PropComparator
from .interfaces import StrategizedProperty
from .relationships import RelationshipProperty
from .util import de_stringify_annotation
from .util import de_stringify_union_elements
from .. import exc as sa_exc
from .. import ForeignKey
from .. import log
@@ -55,13 +55,12 @@ from ..sql.schema import Column
from ..sql.schema import SchemaConst
from ..sql.type_api import TypeEngine
from ..util.typing import de_optionalize_union_types
from ..util.typing import get_args
from ..util.typing import includes_none
from ..util.typing import is_a_type
from ..util.typing import is_fwd_ref
from ..util.typing import is_optional_union
from ..util.typing import is_pep593
from ..util.typing import is_pep695
from ..util.typing import is_union
from ..util.typing import Self
from ..util.typing import typing_get_args
if TYPE_CHECKING:
from ._typing import _IdentityKeyType
@@ -234,7 +233,7 @@ class ColumnProperty(
return self.strategy._have_default_expression # type: ignore
return ("deferred", True) not in self.strategy_key or (
self not in self.parent._readonly_props
self not in self.parent._readonly_props # type: ignore
)
@util.preload_module("sqlalchemy.orm.state", "sqlalchemy.orm.strategies")
@@ -280,8 +279,8 @@ class ColumnProperty(
name = Column(String(64))
extension = Column(String(8))
filename = column_property(name + "." + extension)
path = column_property("C:/" + filename.expression)
filename = column_property(name + '.' + extension)
path = column_property('C:/' + filename.expression)
.. seealso::
@@ -430,7 +429,8 @@ class ColumnProperty(
if TYPE_CHECKING:
def __clause_element__(self) -> NamedColumn[_PT]: ...
def __clause_element__(self) -> NamedColumn[_PT]:
...
def _memoized_method___clause_element__(
self,
@@ -636,11 +636,9 @@ class MappedColumn(
return [
(
self.column,
(
self._sort_order
if self._sort_order is not _NoArg.NO_ARG
else 0
),
self._sort_order
if self._sort_order is not _NoArg.NO_ARG
else 0,
)
]
@@ -663,31 +661,6 @@ class MappedColumn(
# Column will be merged into it in _init_column_for_annotation().
return MappedColumn()
def _adjust_for_existing_column(
self,
decl_scan: _ClassScanMapperConfig,
key: str,
given_column: Column[_T],
) -> Column[_T]:
if (
self._use_existing_column
and decl_scan.inherits
and decl_scan.single
):
if decl_scan.is_deferred:
raise sa_exc.ArgumentError(
"Can't use use_existing_column with deferred mappers"
)
supercls_mapper = class_mapper(decl_scan.inherits, False)
colname = (
given_column.name if given_column.name is not None else key
)
given_column = supercls_mapper.local_table.c.get( # type: ignore[assignment] # noqa: E501
colname, given_column
)
return given_column
def declarative_scan(
self,
decl_scan: _ClassScanMapperConfig,
@@ -702,9 +675,21 @@ class MappedColumn(
) -> None:
column = self.column
column = self.column = self._adjust_for_existing_column(
decl_scan, key, self.column
)
if (
self._use_existing_column
and decl_scan.inherits
and decl_scan.single
):
if decl_scan.is_deferred:
raise sa_exc.ArgumentError(
"Can't use use_existing_column with deferred mappers"
)
supercls_mapper = class_mapper(decl_scan.inherits, False)
colname = column.name if column.name is not None else key
column = self.column = supercls_mapper.local_table.c.get( # type: ignore # noqa: E501
colname, column
)
if column.key is None:
column.key = key
@@ -721,8 +706,6 @@ class MappedColumn(
self._init_column_for_annotation(
cls,
decl_scan,
key,
registry,
extracted_mapped_annotation,
originating_module,
@@ -731,7 +714,6 @@ class MappedColumn(
@util.preload_module("sqlalchemy.orm.decl_base")
def declarative_scan_for_composite(
self,
decl_scan: _ClassScanMapperConfig,
registry: _RegistryType,
cls: Type[Any],
originating_module: Optional[str],
@@ -742,65 +724,61 @@ class MappedColumn(
decl_base = util.preloaded.orm_decl_base
decl_base._undefer_column_name(param_name, self.column)
self._init_column_for_annotation(
cls, decl_scan, key, registry, param_annotation, originating_module
cls, registry, param_annotation, originating_module
)
def _init_column_for_annotation(
self,
cls: Type[Any],
decl_scan: _ClassScanMapperConfig,
key: str,
registry: _RegistryType,
argument: _AnnotationScanType,
originating_module: Optional[str],
) -> None:
sqltype = self.column.type
if is_fwd_ref(
argument, check_generic=True, check_for_plain_string=True
if isinstance(argument, str) or is_fwd_ref(
argument, check_generic=True
):
assert originating_module is not None
argument = de_stringify_annotation(
cls, argument, originating_module, include_generic=True
)
nullable = includes_none(argument)
if is_union(argument):
assert originating_module is not None
argument = de_stringify_union_elements(
cls, argument, originating_module
)
nullable = is_optional_union(argument)
if not self._has_nullable:
self.column.nullable = nullable
our_type = de_optionalize_union_types(argument)
find_mapped_in: Tuple[Any, ...] = ()
our_type_is_pep593 = False
raw_pep_593_type = None
use_args_from = None
if is_pep593(our_type):
our_type_is_pep593 = True
pep_593_components = get_args(our_type)
pep_593_components = typing_get_args(our_type)
raw_pep_593_type = pep_593_components[0]
if nullable:
if is_optional_union(raw_pep_593_type):
raw_pep_593_type = de_optionalize_union_types(raw_pep_593_type)
find_mapped_in = pep_593_components[1:]
elif is_pep695(argument) and is_pep593(argument.__value__):
# do not support nested annotation inside unions ets
find_mapped_in = get_args(argument.__value__)[1:]
use_args_from: Optional[MappedColumn[Any]]
for elem in find_mapped_in:
if isinstance(elem, MappedColumn):
use_args_from = elem
break
nullable = True
if not self._has_nullable:
self.column.nullable = nullable
for elem in pep_593_components[1:]:
if isinstance(elem, MappedColumn):
use_args_from = elem
break
else:
use_args_from = None
our_type_is_pep593 = False
raw_pep_593_type = None
if use_args_from is not None:
self.column = use_args_from._adjust_for_existing_column(
decl_scan, key, self.column
)
if (
not self._has_insert_default
and use_args_from.column.default is not None
@@ -870,7 +848,8 @@ class MappedColumn(
)
if sqltype._isnull and not self.column.foreign_keys:
checks: List[Any]
new_sqltype = None
if our_type_is_pep593:
checks = [our_type, raw_pep_593_type]
else:
@@ -885,23 +864,16 @@ class MappedColumn(
isinstance(our_type, type)
and issubclass(our_type, TypeEngine)
):
raise orm_exc.MappedAnnotationError(
raise sa_exc.ArgumentError(
f"The type provided inside the {self.column.key!r} "
"attribute Mapped annotation is the SQLAlchemy type "
f"{our_type}. Expected a Python type instead"
)
elif is_a_type(our_type):
raise orm_exc.MappedAnnotationError(
else:
raise sa_exc.ArgumentError(
"Could not locate SQLAlchemy Core type for Python "
f"type {our_type} inside the {self.column.key!r} "
"attribute Mapped annotation"
)
else:
raise orm_exc.MappedAnnotationError(
f"The object provided inside the {self.column.key!r} "
"attribute Mapped annotation is not a Python type, "
f"it's the object {our_type!r}. Expected a Python "
"type."
)
self.column._set_type(new_sqltype)