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

GraphQL+SQLAlchemy嵌套类型无法识别问题排查求助

问题分析与解决:'dict' object has no attribute 'skills' in Strawberry GraphQL

核心原因很直接:Strawberry GraphQL是强类型框架,它期望你返回定义好的类型实例,而不是普通字典——哪怕字典的键值和类型的属性完全匹配,它也会尝试通过属性访问(.运算符)来读取数据,而不是字典的键访问([]),所以会抛出这个错误。

下面是几个常见的坑和对应的解决方法:

1. 接口直接返回了字典列表,未转成Strawberry类型实例

假设你定义的Strawberry类型是这样的:

import strawberry

@strawberry.type
class SkillType:
    id: int
    name: str

@strawberry.type
class SkillGroupType:
    category: str
    skills: list[SkillType]

如果你的get_all_skills函数直接返回从SQLAlchemy查询得到的字典列表(比如[{"category": "后端", "skills": [...]}, ...]),肯定会报错。你需要把每个字典显式转换成SkillGroupType和SkillType的实例:

def get_all_skills() -> list[SkillGroupType]:
    # 假设raw_groups是SQLAlchemy查询得到的字典列表
    raw_groups = query_skills_from_db()
    
    # 逐个转成Strawberry类型实例
    return [
        SkillGroupType(
            category=group["category"],
            skills=[SkillType(**skill_dict) for skill_dict in group["skills"]]
        )
        for group in raw_groups
    ]

2. 使用Pydantic但未正确关联Strawberry类型

如果用Pydantic做数据校验,你需要确保Strawberry能识别Pydantic模型,或者把Pydantic实例转成Strawberry类型实例。推荐用strawberry.pydantic.type装饰器直接基于Pydantic模型生成Strawberry类型:

from pydantic import BaseModel
import strawberry

# Pydantic模型
class Skill(BaseModel):
    id: int
    name: str

class SkillGroup(BaseModel):
    category: str
    skills: list[Skill]

# 基于Pydantic模型生成Strawberry类型
@strawberry.pydantic.type(model=Skill)
class SkillType:
    pass

@strawberry.pydantic.type(model=SkillGroup)
class SkillGroupType:
    pass

# 接口返回Pydantic实例列表即可,Strawberry会自动处理
def get_all_skills() -> list[SkillGroupType]:
    raw_data = query_skills_from_db()
    # 先转成Pydantic实例
    skill_groups = [SkillGroup(**item) for item in raw_data]
    return skill_groups

3. SQLAlchemy分组查询的结果未正确解析

如果用SQLAlchemy的func.json_agg等方式聚合技能列表,返回的skills可能是JSON字符串而非Python列表,这时候要先解析成列表再转类型:

import json
from sqlalchemy import func

# SQLAlchemy分组查询
result = db.session.query(
    Skill.category,
    func.json_agg(func.json_build_object('id', Skill.id, 'name', Skill.name)).label('skills')
).group_by(Skill.category).all()

# 解析JSON字符串并转成字典
raw_groups = [
    {
        "category": row.category,
        "skills": json.loads(row.skills)
    }
    for row in result
]

# 再转成Strawberry类型实例(参考方法1)

关键总结

别偷懒直接返回字典,必须把数据转换成你定义的Strawberry类型实例(或关联的Pydantic实例),Strawberry才能正确识别嵌套属性。

内容的提问来源于stack exchange,提问作者hycv

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:20:35