-
-
Notifications
You must be signed in to change notification settings - Fork 499
Open
Labels
Bug 🐛This is something that is not working as expectedThis is something that is not working as expected
Description
Description
1. SQLAlchemyDTO 与 JSONB 字段序列化错误
问题描述
使用 SQLAlchemyDTO 处理包含 JSONB 类型字段的模型时,出现以下错误:
ValueError: dictionary update sequence element #0 has length 1; 2 is required
HTTP 响应返回 500 Internal Server Error。
发生场景
- 框架版本: Litestar 2.x (包括 2.15.1 和 2.18.0)
- 数据库: PostgreSQL (使用
JSONB) - 模型定义: 字段被定义为
Mapped[dict[str, Any]]或Mapped[dict] - 触发时机: DTO 序列化模型数据返回给客户端时
URL to code causing the issue
No response
MCVE
### 有问题的代码
from typing import Any
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import Mapped, mapped_column
class MyModel(Base):
# 这种定义会导致 DTO 序列化出错
config: Mapped[dict[str, Any]] = mapped_column(JSONB, default=dict)Steps to reproduce
原因分析
Litestar DTO 生成器在处理 Mapped[dict[...]] 类型时,会尝试对数据进行严格的类型验证和转换。对于 JSONB 字段,底层处理逻辑可能错误地将数据视为需要解包的序列,导致转换失败。
解决方案
将字段的类型提示修改为 Mapped[Any]:
from typing import Any
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import Mapped, mapped_column
class MyModel(Base):
# 修改类型提示为 Any,绕过 DTO 的类型检查
config: Mapped[Any] = mapped_column(JSONB, default=dict)影响
- 数据库: 无影响,依然是 JSONB 类型
- API 文档: OpenAPI 中该字段可能显示为通用对象类型
- 类型检查: IDE 不会提供字典相关的代码提示
2. SQLAlchemyDTO 循环引用错误
问题描述
当模型之间存在双向关系时,DTO 序列化可能导致无限递归或错误。
解决方案
在 SQLAlchemyDTOConfig 中排除反向引用字段:
class ParentReadDTO(SQLAlchemyDTO[Parent]):
config = SQLAlchemyDTOConfig(
exclude={
"created_at",
"updated_at",
"children.parent", # 排除子对象中的父引用
},
max_nested_depth=1, # 限制嵌套深度
)示例
# 模型定义
class TemplateSuite(Base):
items: Mapped[list[TemplateSuiteItem]] = relationship(back_populates="suite")
class TemplateSuiteItem(Base):
suite: Mapped[TemplateSuite] = relationship(back_populates="items")
# DTO 配置 - 排除 items.suite 避免循环
class TemplateSuiteReadDTO(SQLAlchemyDTO[TemplateSuite]):
config = SQLAlchemyDTOConfig(
exclude={
"created_at",
"updated_at",
"items.created_at",
"items.updated_at",
"items.suite", # 关键:打破循环引用
},
max_nested_depth=1,
)Screenshots
No response
Logs
Litestar Version
Litestar 2.18.0 + advanced-alchemy 1.8.0
Mapped[dict] ❌
Mapped[dict[str, Any]] ❌
Mapped[Any] ✅
Platform
- Linux
- Mac
- Windows
- Other (Please specify in the description above)
Metadata
Metadata
Assignees
Labels
Bug 🐛This is something that is not working as expectedThis is something that is not working as expected