flask-sqlalchemy icon indicating copy to clipboard operation
flask-sqlalchemy copied to clipboard

test_explicit_table[db2,db4] failing with sqlalchemy 2.0.36

Open mweinelt opened this issue 11 months ago • 0 comments

After upgrading sqlalchemy from 2.0.34 to 2.0.36 we started seeing two tests fail on flask-sqlalchemy 3.1.1 on Python 3.12.7.

  • Update sqlalchemy to 2.0.36

Tests should succeed, since this release is in the allowed version range, but what happens is this:

___________________________ test_explicit_table[db2] ___________________________

db = <SQLAlchemy>

    def test_explicit_table(db: SQLAlchemy) -> None:
        user_table = db.Table(
            "user",
            sa.Column("id", sa.Integer, primary_key=True),
            bind_key="auth",
        )
    
>       class User(db.Model):

tests/test_model_bind.py:85: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/nix/store/l1qbv92ydl23da6vhzq3b3xmm7nbphs0-python3.12-flask-sqlalchemy-3.1.1/lib/python3.12/site-packages/flask_sqlalchemy/model.py:124: in __init_subclass__
    super().__init_subclass__(**kwargs)
/nix/store/l1qbv92ydl23da6vhzq3b3xmm7nbphs0-python3.12-flask-sqlalchemy-3.1.1/lib/python3.12/site-packages/flask_sqlalchemy/model.py:214: in __init_subclass__
    super().__init_subclass__(**kwargs)
/nix/store/xk73dbr0g48273zpq857nsy677zx98z3-python3.12-sqlalchemy-2.0.36/lib/python3.12/site-packages/sqlalchemy/orm/decl_api.py:617: in __init_subclass__
    super().__init_subclass__(**kw)
/nix/store/xk73dbr0g48273zpq857nsy677zx98z3-python3.12-sqlalchemy-2.0.36/lib/python3.12/site-packages/sqlalchemy/orm/decl_api.py:836: in __init_subclass__
    _as_declarative(cls._sa_registry, cls, cls.__dict__)
/nix/store/xk73dbr0g48273zpq857nsy677zx98z3-python3.12-sqlalchemy-2.0.36/lib/python3.12/site-packages/sqlalchemy/orm/decl_base.py:244: in _as_declarative
    return _MapperConfig.setup_mapping(registry, cls, dict_, None, {})
/nix/store/xk73dbr0g48273zpq857nsy677zx98z3-python3.12-sqlalchemy-2.0.36/lib/python3.12/site-packages/sqlalchemy/orm/decl_base.py:325: in setup_mapping
    return _ClassScanMapperConfig(
/nix/store/xk73dbr0g48273zpq857nsy677zx98z3-python3.12-sqlalchemy-2.0.36/lib/python3.12/site-packages/sqlalchemy/orm/decl_base.py:563: in __init__
    self._setup_dataclasses_transforms()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.orm.decl_base._ClassScanMapperConfig object at 0x7ffff44eb3e0>

    def _setup_dataclasses_transforms(self) -> None:
        dataclass_setup_arguments = self.dataclass_setup_arguments
        if not dataclass_setup_arguments:
            return
    
        # can't use is_dataclass since it uses hasattr
        if "__dataclass_fields__" in self.cls.__dict__:
            raise exc.InvalidRequestError(
                f"Class {self.cls} is already a dataclass; ensure that "
                "base classes / decorator styles of establishing dataclasses "
                "are not being mixed. "
                "This can happen if a class that inherits from "
                "'MappedAsDataclass', even indirectly, is been mapped with "
                "'@registry.mapped_as_dataclass'"
            )
    
        # can't create a dataclass if __table__ is already there. This would
        # fail an assertion when calling _get_arguments_for_make_dataclass:
        # assert False, "Mapped[] received without a mapping declaration"
        if "__table__" in self.cls.__dict__:
>           raise exc.InvalidRequestError(
                f"Class {self.cls} already defines a '__table__'. "
                "ORM Annotated Dataclasses do not support a pre-existing "
                "'__table__' element"
            )
E           sqlalchemy.exc.InvalidRequestError: Class <class 'test_model_bind.test_explicit_table.<locals>.User'> already defines a '__table__'. ORM Annotated Dataclasses do not support a pre-existing '__table__' element

/nix/store/xk73dbr0g48273zpq857nsy677zx98z3-python3.12-sqlalchemy-2.0.36/lib/python3.12/site-packages/sqlalchemy/orm/decl_base.py:1074: InvalidRequestError
___________________________ test_explicit_table[db4] ___________________________

db = <SQLAlchemy>

    def test_explicit_table(db: SQLAlchemy) -> None:
        user_table = db.Table(
            "user",
            sa.Column("id", sa.Integer, primary_key=True),
            bind_key="auth",
        )
    
>       class User(db.Model):

tests/test_model_bind.py:85: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/nix/store/l1qbv92ydl23da6vhzq3b3xmm7nbphs0-python3.12-flask-sqlalchemy-3.1.1/lib/python3.12/site-packages/flask_sqlalchemy/model.py:124: in __init_subclass__
    super().__init_subclass__(**kwargs)
/nix/store/l1qbv92ydl23da6vhzq3b3xmm7nbphs0-python3.12-flask-sqlalchemy-3.1.1/lib/python3.12/site-packages/flask_sqlalchemy/model.py:214: in __init_subclass__
    super().__init_subclass__(**kwargs)
/nix/store/xk73dbr0g48273zpq857nsy677zx98z3-python3.12-sqlalchemy-2.0.36/lib/python3.12/site-packages/sqlalchemy/orm/decl_api.py:617: in __init_subclass__
    super().__init_subclass__(**kw)
/nix/store/xk73dbr0g48273zpq857nsy677zx98z3-python3.12-sqlalchemy-2.0.36/lib/python3.12/site-packages/sqlalchemy/orm/decl_api.py:958: in __init_subclass__
    _as_declarative(cls._sa_registry, cls, cls.__dict__)
/nix/store/xk73dbr0g48273zpq857nsy677zx98z3-python3.12-sqlalchemy-2.0.36/lib/python3.12/site-packages/sqlalchemy/orm/decl_base.py:244: in _as_declarative
    return _MapperConfig.setup_mapping(registry, cls, dict_, None, {})
/nix/store/xk73dbr0g48273zpq857nsy677zx98z3-python3.12-sqlalchemy-2.0.36/lib/python3.12/site-packages/sqlalchemy/orm/decl_base.py:325: in setup_mapping
    return _ClassScanMapperConfig(
/nix/store/xk73dbr0g48273zpq857nsy677zx98z3-python3.12-sqlalchemy-2.0.36/lib/python3.12/site-packages/sqlalchemy/orm/decl_base.py:563: in __init__
    self._setup_dataclasses_transforms()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.orm.decl_base._ClassScanMapperConfig object at 0x7ffff482b6b0>

    def _setup_dataclasses_transforms(self) -> None:
        dataclass_setup_arguments = self.dataclass_setup_arguments
        if not dataclass_setup_arguments:
            return
    
        # can't use is_dataclass since it uses hasattr
        if "__dataclass_fields__" in self.cls.__dict__:
            raise exc.InvalidRequestError(
                f"Class {self.cls} is already a dataclass; ensure that "
                "base classes / decorator styles of establishing dataclasses "
                "are not being mixed. "
                "This can happen if a class that inherits from "
                "'MappedAsDataclass', even indirectly, is been mapped with "
                "'@registry.mapped_as_dataclass'"
            )
    
        # can't create a dataclass if __table__ is already there. This would
        # fail an assertion when calling _get_arguments_for_make_dataclass:
        # assert False, "Mapped[] received without a mapping declaration"
        if "__table__" in self.cls.__dict__:
>           raise exc.InvalidRequestError(
                f"Class {self.cls} already defines a '__table__'. "
                "ORM Annotated Dataclasses do not support a pre-existing "
                "'__table__' element"
            )
E           sqlalchemy.exc.InvalidRequestError: Class <class 'test_model_bind.test_explicit_table.<locals>.User'> already defines a '__table__'. ORM Annotated Dataclasses do not support a pre-existing '__table__' element

/nix/store/xk73dbr0g48273zpq857nsy677zx98z3-python3.12-sqlalchemy-2.0.36/lib/python3.12/site-packages/sqlalchemy/orm/decl_base.py:1074: InvalidRequestError

Environment:

  • Python version: 3.12.7
  • Flask-SQLAlchemy version: 3.1.1
  • SQLAlchemy version: 2.0.36

mweinelt avatar Nov 15 '24 02:11 mweinelt