You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用dataclass+mapper_registry.mapped的SQLAlchemy类无法实例化问题

报错原因与解决方案

问题产生原因

  • Python装饰器的执行逻辑是从靠近类的装饰器开始,依次向远离类的装饰器执行,最终外层装饰器的返回值会替换原类。
  • 你当前的装饰器顺序是@dataclass在下层、@mapper_registry.mapped在上层,执行逻辑等价于mapper_registry.mapped(dataclass(Token)):@dataclass首先生成了接收name、symbol、decimals三个参数的构造方法,随后执行的SQLAlchemy映射装饰器默认会自动生成仅接收self的无参构造方法,直接覆盖了dataclass生成的构造方法,因此实例化时传参就会抛出参数数量不匹配的错误。

解决方案

方案1:调换装饰器顺序(最常用)

将@dataclass放在更靠近类的位置,保证dataclass生成的构造方法不会被SQLAlchemy覆盖,修改后代码如下:

from dataclasses import dataclass

from sqlalchemy import String, Integer, Column, Table
from sqlalchemy.orm import registry


mapper_registry = registry()

# 调换两个装饰器的顺序
@mapper_registry.mapped
@dataclass
class Token:
    __table__ = Table(
        "token",
        mapper_registry.metadata,
        Column("name", String(), primary_key=True),
        Column("symbol", String(), nullable=False),
        Column("decimals", Integer(), nullable=False),
    )

    name: str
    symbol: str
    decimals: int

# 可正常实例化
Token("name", "symbol", 1)

方案2:关闭SQLAlchemy的自动构造方法生成

如果你不想调整装饰器顺序,可以给mapped装饰器传入init=False参数,告知SQLAlchemy不要自动生成构造方法,沿用dataclass生成的构造方法即可:

@dataclass
@mapper_registry.mapped(init=False)
class Token:
    # 其余代码保持不变

内容的提问来源于stack exchange,提问作者José D.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 09:45:03