Skip to content

SQLAlchemy 2.1 MappedAsDataclass compatibility #1420

@krzysdz

Description

@krzysdz

A change to SQLAlchemy 2.1 dataclass handling made it incompatible with Flask-SQLAlchemy. This simple code snippet is enough to reproduce the problem:

from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import DeclarativeBase, MappedAsDataclass

class BaseModel(DeclarativeBase, MappedAsDataclass):
    pass

db = SQLAlchemy(model_class=BaseModel)
# sqlalchemy.exc.InvalidRequestError: Class <class '__main__.FlaskSQLAlchemyBase'> 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'

Flask-SQLAlchemy uses types.new_class() to re-create user's model_class with added mixins. Because it also copies all attributes from the class namespace, the newly created class already has some attributes (specifically __dataclass_fields__) that MappedAsDataclass tries to add later when its __init_subclass__() is executed again. Since these attributes already exist, SQLAlchemy throws an error.

elif len(declarative_bases) == 1:
body = dict(model_class.__dict__)
body["__fsa__"] = self
mixin_classes = [BindMixin, NameMixin, Model]
if disable_autonaming:
mixin_classes.remove(NameMixin)
model = types.new_class(
"FlaskSQLAlchemyBase",
(*mixin_classes, *model_class.__bases__),
{"metaclass": type(declarative_bases[0])},
lambda ns: ns.update(body),
)

I asked about it in the SQLAlchemy repository and it is not a bug in SQLAlchemy (sqlalchemy/sqlalchemy#13160).

Environment:

  • Python version: 3.14.3
  • Flask-SQLAlchemy version: 3.1.1
  • SQLAlchemy version: 2.1.0b1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions