]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Improved error message in orm annotated declarative
authorFederico Caselli <cfederico87@gmail.com>
Wed, 14 Dec 2022 21:18:58 +0000 (22:18 +0100)
committerFederico Caselli <cfederico87@gmail.com>
Wed, 14 Dec 2022 21:19:29 +0000 (22:19 +0100)
Fixes: #8980
Change-Id: I32c4cf8715ee43fa8415f0102394ddd43b1fee0a

lib/sqlalchemy/orm/properties.py
test/orm/declarative/test_tm_future_annotations_sync.py
test/orm/declarative/test_typed_mapping.py

index 21df672eca61a906957841dc8d2fc130eac745d1..04b011f091e40d82e89e7880308642996fa63cf9 100644 (file)
@@ -50,6 +50,7 @@ from ..sql.base import _NoArg
 from ..sql.roles import DDLConstraintColumnRole
 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 de_stringify_annotation
 from ..util.typing import de_stringify_union_elements
@@ -678,7 +679,10 @@ class MappedColumn(
                 return
 
         self._init_column_for_annotation(
-            cls, registry, extracted_mapped_annotation, originating_module
+            cls,
+            registry,
+            extracted_mapped_annotation,
+            originating_module,
         )
 
     @util.preload_module("sqlalchemy.orm.decl_base")
@@ -760,9 +764,20 @@ class MappedColumn(
                 if new_sqltype is not None:
                     break
             else:
-                raise sa_exc.ArgumentError(
-                    f"Could not locate SQLAlchemy Core "
-                    f"type for Python type: {our_type}"
-                )
+                if isinstance(our_type, TypeEngine) or (
+                    isinstance(our_type, type)
+                    and issubclass(our_type, TypeEngine)
+                ):
+                    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"
+                    )
+                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"
+                    )
 
             self.column._set_type(new_sqltype)
index 5d1b6b199e9c3f5b5fc28d614362bdcd10603378..787e09aac9711c7682d351a54b93a7fbca0e1454 100644 (file)
@@ -402,7 +402,8 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
 
         with expect_raises_message(
             sa_exc.ArgumentError,
-            "Could not locate SQLAlchemy Core type for Python type: .*MyClass",
+            "Could not locate SQLAlchemy Core type for Python type "
+            ".*MyClass.* inside the 'data' attribute Mapped annotation",
         ):
 
             class User(decl_base):
@@ -411,6 +412,21 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
                 id: Mapped[int] = mapped_column(primary_key=True)
                 data: Mapped[MyClass] = mapped_column()
 
+    def test_construct_lhs_sqlalchemy_type(self, decl_base):
+
+        with expect_raises_message(
+            sa_exc.ArgumentError,
+            "The type provided inside the 'data' attribute Mapped "
+            "annotation is the SQLAlchemy type .*BigInteger.*. Expected "
+            "a Python type instead",
+        ):
+
+            class User(decl_base):
+                __tablename__ = "users"
+
+                id: Mapped[int] = mapped_column(primary_key=True)
+                data: Mapped[BigInteger] = mapped_column()
+
     def test_construct_rhs_type_override_lhs(self, decl_base):
         class Element(decl_base):
             __tablename__ = "element"
index ffa640d4cd3630ecf7ae4e99881993f6cbe22431..da73104e26a5bdbcee3f88abc124b17fa3121138 100644 (file)
@@ -393,7 +393,8 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
 
         with expect_raises_message(
             sa_exc.ArgumentError,
-            "Could not locate SQLAlchemy Core type for Python type: .*MyClass",
+            "Could not locate SQLAlchemy Core type for Python type "
+            ".*MyClass.* inside the 'data' attribute Mapped annotation",
         ):
 
             class User(decl_base):
@@ -402,6 +403,21 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
                 id: Mapped[int] = mapped_column(primary_key=True)
                 data: Mapped[MyClass] = mapped_column()
 
+    def test_construct_lhs_sqlalchemy_type(self, decl_base):
+
+        with expect_raises_message(
+            sa_exc.ArgumentError,
+            "The type provided inside the 'data' attribute Mapped "
+            "annotation is the SQLAlchemy type .*BigInteger.*. Expected "
+            "a Python type instead",
+        ):
+
+            class User(decl_base):
+                __tablename__ = "users"
+
+                id: Mapped[int] = mapped_column(primary_key=True)
+                data: Mapped[BigInteger] = mapped_column()
+
     def test_construct_rhs_type_override_lhs(self, decl_base):
         class Element(decl_base):
             __tablename__ = "element"