summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Caselli <cfederico87@gmail.com>2022-12-14 22:18:58 +0100
committerFederico Caselli <cfederico87@gmail.com>2022-12-14 22:19:29 +0100
commit1e05901bbe88f86060db13ceffc415e098e653f4 (patch)
tree5c588d44e34acacff8d714031876237b57830ad1
parenta8d76cff39dbaf6354d42d35cd68332df469d124 (diff)
downloadsqlalchemy-1e05901bbe88f86060db13ceffc415e098e653f4.tar.gz
Improved error message in orm annotated declarative
Fixes: #8980 Change-Id: I32c4cf8715ee43fa8415f0102394ddd43b1fee0a
-rw-r--r--lib/sqlalchemy/orm/properties.py25
-rw-r--r--test/orm/declarative/test_tm_future_annotations_sync.py18
-rw-r--r--test/orm/declarative/test_typed_mapping.py18
3 files changed, 54 insertions, 7 deletions
diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py
index 21df672ec..04b011f09 100644
--- a/lib/sqlalchemy/orm/properties.py
+++ b/lib/sqlalchemy/orm/properties.py
@@ -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)
diff --git a/test/orm/declarative/test_tm_future_annotations_sync.py b/test/orm/declarative/test_tm_future_annotations_sync.py
index 5d1b6b199..787e09aac 100644
--- a/test/orm/declarative/test_tm_future_annotations_sync.py
+++ b/test/orm/declarative/test_tm_future_annotations_sync.py
@@ -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"
diff --git a/test/orm/declarative/test_typed_mapping.py b/test/orm/declarative/test_typed_mapping.py
index ffa640d4c..da73104e2 100644
--- a/test/orm/declarative/test_typed_mapping.py
+++ b/test/orm/declarative/test_typed_mapping.py
@@ -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"