FastAPI使用Tortoise-ORM写入外键字段报AttributeError错如何解决
问题根因
你触发报错的核心原因是Tortoise-ORM对外键字段的自动命名规则:
- 你在
project模型中定义的外键字段名为user_id,Tortoise会自动为该外键对应的数据库ID字段追加_id后缀,实际映射的数据库存值字段为user_id_id - 你直接给
user_id参数传整数1,Tortoise会把这个值当成UserModel实例来解析,自然就触发了int对象没有_saved_in_db属性的报错 - 额外注意:
create方法已经自动执行了数据保存操作,后续再调用await project.save()属于冗余操作,可以直接删除
修复方案
方案1:传实际的UserModel实例
先查询到对应的用户实例,再传给外键字段:
@auth_router.post("/add_project") async def register(form_data: users.project = Depends()): # 先查询对应ID的用户实例 user = await UserModel.get(id=1) # 将实例传给外键字段 project = await users.project.create(project_name=form_data.project_name, user_id=user)
方案2:直接传外键ID值(更高效,不需要额外查询)
用Tortoise自动生成的带_id后缀的字段名传ID值:
@auth_router.post("/add_project") async def register(form_data: users.project = Depends()): # 外键字段名追加_id后传整数ID即可 project = await users.project.create(project_name=form_data.project_name, user_id_id=1)
可选优化(避免后续命名混淆)
建议修改模型中的外键字段名,不要带_id后缀,符合Tortoise的命名规范:
# 修改后的project模型 class project(models.Model): id = fields.IntField(pk=True) project_name = fields.CharField(null=False, max_length=255) # 外键字段名改为user,不要带_id user = fields.ForeignKeyField( "models.UserModel", related_name="items", null=True)
修改后你就可以直接用符合直觉的user_id=1传ID值:
project = await users.project.create(project_name=form_data.project_name, user_id=1)
内容的提问来源于stack exchange,提问作者Sandeepkumar Bandi
相关产品推荐
相关产品推荐

