微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 PydanticMeta [FastAPI, Tortoise ORM]

如何解决如何使用 PydanticMeta [FastAPI, Tortoise ORM]

我目前正在开发个人财务 api,我正在努力恢复一些在 pydantic 模型中异步的函数。 我正在使用 FastApi、pydantic 和 Tortoise ORM。 基本上目的是返回给定用户的所有 Budget.amount (month_base) 的总和,但问题是这个函数是异步的,当我将它作为计算字段传递给 PydanticMeta 类时,它不会等待,因此返回值不是正确的类型,如以下错误所述:

ERROR:hypercorn.error:Asgi 框架中的错误 [...] 文件“pydantic/main.py”,第 573 行,在 pydantic.main.BaseModel.from_orm pydantic.error_wrappers.ValidationError: 1 用户验证错误 month_base 值不是有效的浮点数 (type=type_error.float)

/home/jon/ml-v3/venv/lib/python3.8/site-packages/tortoise/contrib/pydantic/base.py:88: RuntimeWarning: coroutine 'User.month_base' 从未等待

我在models.py中的代码

class SoftDeleteMixin:
    deleted = fields.BooleanField(default=False)
    deletion_date = fields.DatetimeField(null=True)

    def soft_delete(self):
        """
        Annotate the object as deleted and saves the deletion_date
        ---Return---
        False if the object is already deleted else True
        """
        if self.deleted:
            return False
        self.deleted = True
        self.deletion_date = datetime.today()
        return True

    @classmethod
    async def get_non_deleted(cls,user_id: int):
        return await cls.filter(Q(user_id=user_id) & Q(deleted=False))
    

class User(Model):
        id = fields.IntField(pk=True)
        gender = fields.IntEnumField(Gender,default=Gender.not_specified)
        configured = fields.BooleanField(default=False)
        start_date = fields.DatetimeField(null=True)
        email = fields.CharField(max_length=100,unique=True,index=True)
        full_name = fields.CharField(max_length=50)
        password_hash = fields.CharField(max_length=128,null=True)
        confirmed = fields.BooleanField(default=False)
        general_terms_and_conditions_of_sale_signed = fields.BooleanField(default=False)
        privacy_policy_signed = fields.BooleanField(default=False)
        signature_date = fields.DatetimeField(null=True)
        # One-To-Many relationships
        budgets: fields.ReverseRelation['Budget']
        origins: fields.ReverseRelation['Origin']
        long_budgets: fields.ReverseRelation['LongBudget']
        stocks: fields.ReverseRelation['Stock']
        outcomes: fields.ReverseRelation['Outcome']
        incomes: fields.ReverseRelation['Income']
        costs: fields.ReverseRelation['Cost']
        transfer: fields.ReverseRelation['Transfer']
        images: fields.ReverseRelation['Image']
    
    async def get_budgets(self):
        return await Budget.get_non_deleted(user_id=self.id).order_by('order')

    async def month_base(self) -> float:
        return sum(map(lambda budget: budget.month_budget,await self.get_budgets()))
    class PydanticMeta:
        computed = ['month_base',]
        exclude = ['password_hash','general_terms_and_conditions_of_sale_signed','privacy_policy_signed','signature_date','confirmed']

我在 schemas.py 中的代码

User = pydantic_model_creator(models.User,name='User')
UserIn = pydantic_model_creator(models.User,exclude=('configured','start_date'),name='UserIn',exclude_readonly=True)

我在 main.py 中的代码

async def get_current_user(token: str = Depends(oauth2_schema)):
    try:
        payload = jwt.decode(token,JWT_SECRET,algorithms=['HS256'])
        user = await User.get(id=payload.get('id'))
    except:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,detail='Invalid username or password'
        )
    return await sch.User.from_tortoise_orm(user)
@app.get('/user',response_model=sch.User)
async def read_user(user: sch.User = Depends(get_current_user)):
    return user

我应该如何继续将我的 month_budget 字段传递给我的用户架构,但指定给 pydanticModel 以等待其结果? 感谢您的帮助!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。