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
相关产品推荐
相关产品推荐

