summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/decl_base.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-10-21 00:11:10 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2022-10-21 11:48:35 -0400
commit8370edb4ccca2055635107855b58c795fccbeaf1 (patch)
tree5f63704726762dbf9b3a1496ce18240a91afd905 /lib/sqlalchemy/orm/decl_base.py
parentbfe36f11fb423f2318166162d95941beef3cbaaa (diff)
downloadsqlalchemy-8370edb4ccca2055635107855b58c795fccbeaf1.tar.gz
allow legacy forms with __allow_unmapped__
Improved support for legacy 1.4 mappings that use annotations which don't include ``Mapped[]``, by ensuring the ``__allow_unmapped__`` attribute can be used to allow such legacy annotations to pass through Annotated Declarative without raising an error and without being interpreted in an ORM runtime context. Additionally improved the error message generated when this condition is detected, and added more documentation for how this situation should be handled. Unfortunately the 1.4 WARN_SQLALCHEMY_20 migration warning cannot detect this particular configurational issue at runtime with its current architecture. Fixes: #8692 Change-Id: I5c642bcc1ebb7816f9470ec9bb0951550b6d55f1
Diffstat (limited to 'lib/sqlalchemy/orm/decl_base.py')
-rw-r--r--lib/sqlalchemy/orm/decl_base.py36
1 files changed, 27 insertions, 9 deletions
diff --git a/lib/sqlalchemy/orm/decl_base.py b/lib/sqlalchemy/orm/decl_base.py
index ef2c2f3c9..4e79ecc6f 100644
--- a/lib/sqlalchemy/orm/decl_base.py
+++ b/lib/sqlalchemy/orm/decl_base.py
@@ -1199,6 +1199,11 @@ class _ClassScanMapperConfig(_MapperConfig):
cls, "_sa_decl_prepare_nocascade", strict=True
)
+ expect_annotations_wo_mapped = (
+ self.allow_unmapped_annotations
+ or self.is_dataclass_prior_to_mapping
+ )
+
for k in list(collected_attributes):
if k in ("__table__", "__tablename__", "__mapper_args__"):
@@ -1275,15 +1280,28 @@ class _ClassScanMapperConfig(_MapperConfig):
) = self.collected_annotations.get(
k, (None, None, None, False, None)
)
- value.declarative_scan(
- self.registry,
- cls,
- k,
- mapped_container,
- annotation,
- extracted_mapped_annotation,
- is_dataclass,
- )
+
+ # issue #8692 - don't do any annotation interpretation if
+ # an annotation were present and a container such as
+ # Mapped[] etc. were not used. If annotation is None,
+ # do declarative_scan so that the property can raise
+ # for required
+ if mapped_container is not None or annotation is None:
+ value.declarative_scan(
+ self.registry,
+ cls,
+ k,
+ mapped_container,
+ annotation,
+ extracted_mapped_annotation,
+ is_dataclass,
+ )
+ else:
+ # assert that we were expecting annotations
+ # without Mapped[] were going to be passed.
+ # otherwise an error should have been raised
+ # by util._extract_mapped_subtype before we got here.
+ assert expect_annotations_wo_mapped
if (
isinstance(value, (MapperProperty, _MapsColumns))