Skip to content

support NewType similarly to Annotated #9175

Closed
Listed in
Closed
@lukasjuhrich

Description

@lukasjuhrich

Describe the bug

Trying to use NewTypes for a column annotation causes a crash without any reference as to what column caused the problem.

Even if using NewTypes is not supported (which I assumed it was), I would have expected sqlalchemy to not crash internally, but handle this case and throw an exception to communicate to me

  • what the relevant column with the problem is (I had to bisect for a while)
  • that NewType-mapped columns are currently not supported.

If NewTypes are nontrivial to support then a remark in the docs + „what's new“ document might be helpful (the search term NewType had 0 occurences in the docs).

(hope using an issue was the right call. This form with MWE/Backtrace fields felt more appropriate.)

To Reproduce

from datetime import datetime
import typing as t
from sqlalchemy import *
from sqlalchemy.orm import *
DateTimeTz = t.NewType("DateTimeTz", datetime)
class Base(DeclarativeBase):
    type_annotation_map = {DateTimeTz: DateTime}
class Foo(Base):
    __tablename__ = "foo"
    id: Mapped[int] = mapped_column(primary_key=True)
    dt: Mapped[DateTimeTz]

Error

Traceback (most recent call last):
  File "/opt/pycroft/app/test.py", line 8, in <module>
    class Foo(Base):
  File "/opt/pycroft/venv/lib/python3.10/site-packages/sqlalchemy/orm/decl_api.py", line 768, in __init_subclass__
    _as_declarative(cls._sa_registry, cls, cls.__dict__)
  File "/opt/pycroft/venv/lib/python3.10/site-packages/sqlalchemy/orm/decl_base.py", line 246, in _as_declarative
    return _MapperConfig.setup_mapping(registry, cls, dict_, None, {})
  File "/opt/pycroft/venv/lib/python3.10/site-packages/sqlalchemy/orm/decl_base.py", line 327, in setup_mapping
    return _ClassScanMapperConfig(
  File "/opt/pycroft/venv/lib/python3.10/site-packages/sqlalchemy/orm/decl_base.py", line 569, in __init__
    self._extract_mappable_attributes()
  File "/opt/pycroft/venv/lib/python3.10/site-packages/sqlalchemy/orm/decl_base.py", line 1388, in _extract_mappable_attributes
    value.declarative_scan(
  File "/opt/pycroft/venv/lib/python3.10/site-packages/sqlalchemy/orm/properties.py", line 681, in declarative_scan
    self._init_column_for_annotation(
  File "/opt/pycroft/venv/lib/python3.10/site-packages/sqlalchemy/orm/properties.py", line 763, in _init_column_for_annotation
    new_sqltype = registry._resolve_type(check_type)
  File "/opt/pycroft/venv/lib/python3.10/site-packages/sqlalchemy/orm/decl_api.py", line 1167, in _resolve_type
    search = python_type_type.__mro__
AttributeError: 'NewType' object has no attribute '__mro__'. Did you mean: '__or__'?

Versions

  • OS: Linux 6.0.10 in Docker
  • Python: 3.10.x
  • SQLAlchemy: 2.0.0
  • Database: None
  • DBAPI (eg: psycopg, cx_oracle, mysqlclient): None

Additional context

I have a type decorator wrapping DateTime which still translates to python's datetime, however existence of a tzinfo is ensured. Since python does not distinguish between tz-less and tz-aware datetimes, the NewType is necessary; a type alias won't do to ensure tz-awareness on the type checking level.

Activity

lukasjuhrich

lukasjuhrich commented on Jan 29, 2023

@lukasjuhrich
Author

Explicitly setting dt: Mapped[DateTimeTz] = mapped_column(DateTime) seems to be a workaround.

added
bugSomething isn't working
orm - annotated declarativeissues with the new annotations-based declarative ORM approach
near-term releaseaddition to the milestone which indicates this should be in a near-term release
and removed
requires triageNew issue that requires categorization
on Jan 29, 2023
added this to the 2.0.x milestone on Jan 29, 2023
zzzeek

zzzeek commented on Jan 29, 2023

@zzzeek
Member

I would assume we handle NewType the same way we do Annotated, so the codepaths that are checking for Annotated need to be augmented for this as well.

changed the title [-]SQLAlchemy v2 crashes when trying to map columns with `NewType`[/-] [+]support NewType similarly to Annotated[/+] on Jan 29, 2023
sqla-tester

sqla-tester commented on Jan 30, 2023

@sqla-tester
Collaborator

Mike Bayer has proposed a fix for this issue in the main branch:

support NewType in type_annotation_map https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4408

added a commit that references this issue on Feb 9, 2024
a21c715
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingnear-term releaseaddition to the milestone which indicates this should be in a near-term releaseorm - annotated declarativeissues with the new annotations-based declarative ORM approach

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @zzzeek@sqla-tester@lukasjuhrich

        Issue actions

          support NewType similarly to Annotated · Issue #9175 · sqlalchemy/sqlalchemy