简体   繁体   English

快速 API - MySQL - SQLAlchemy:在 Pydantic 模型中获取 ValidationError 'Invalid type'

[英]Fast API - MySQL - SQLAlchemy: Get ValidationError 'Invalid type' in Pydantic Model

I'm fairly new to this framework, but i'm working on a timesheet application (API) for a small company.我对这个框架还很陌生,但我正在为一家小公司开发时间表应用程序 (API)。

The issue i have is that when i select a time value from mysql i got the following error in the pydantic module:我遇到的问题是,当我从 mysql 中选择一个时间值时,在 pydantic 模块中出现以下错误:

pydantic.error_wrappers.ValidationError: 2 validation errors for TimeSheetRange 
response -> 0 -> total   
invalid type; expected time, string, bytes, int or float (type=type_error) 
response -> 1 -> total   
invalid type; expected time, string, bytes, int or float (type=type_error)

I have tried a lot of workarounds to get the time to string from mysql with to_char() which also failed, but i rather want to know what the issue is here as i would like to use the data type time...我已经尝试了很多解决方法来获得时间从 mysql 使用to_char()字符串也失败了,但我更想知道这里的问题是什么,因为我想使用数据类型时间...

schemas.py模式.py

from typing import List, Optional
from datetime import date, time, datetime

from pydantic import BaseModel
from . import models

...


class TimeSheetRange(BaseModel):
    user_id: int
    start: date
    total: time

    class Config:
        orm_mode = True

crud.py crud.py

def get_timesheet_by_date_range_and_user(db: Session, user_id=int, date_start=datetime, date_end=datetime):
    return db.query(models.TimeSheet.user_id, \
                    func.date(models.TimeSheet.start).label('start'), \
                    func.sec_to_time(func.sum(func.timediff(models.TimeSheet.end,models.TimeSheet.start))).label('total') ) \
            .filter(models.TimeSheet.user_id == user_id) \
            .filter(func.date(models.TimeSheet.start) >= date_start) \
            .filter(func.date(models.TimeSheet.end) <= date_end) \
            .group_by(func.date(models.TimeSheet.start)) \
            .all()

main.py主文件

@app.get("/timesheets/range/", response_model=List[schemas.TimeSheetRange])
    def read_timesheets(user_id: int, date_start:date = datetime.now().date(), date_end:date = datetime.now().date(), db: Session = Depends(get_db)):
        timesheets = crud.get_timesheet_by_date_range_and_user(db, user_id=user_id, date_start=date_start, date_end=date_end)
        return timesheets

And the SQL Query that is build with a result:以及使用结果构建的 SQL 查询:

SELECT 
    timesheet.user_id AS timesheet_user_id, 
    date(timesheet.start) AS start,
    sec_to_time(sum(timediff(timesheet.end, timesheet.start))) AS total  
FROM 
    timesheet  
WHERE 
    timesheet.user_id = 7 
AND  
    date(timesheet.start) >= '2020-09-20' 
AND 
    date(timesheet.end) <= '2020-09-22' 
GROUP BY 
    date(timesheet.start);
+-------------------+------------+----------+
| timesheet_user_id | start      | total    |
+-------------------+------------+----------+
|                 7 | 2020-09-20 | 17:50:47 |
|                 7 | 2020-09-21 | 18:21:11 |
+-------------------+------------+----------+

Is there something wrong with the datatype time or am i missing something really stupid?数据类型time还是我错过了一些非常愚蠢的东西?

I think the issue here is that the Pydantic model you are using is expecting a time object type, when it should be expecting a timedelta type as your sql statement seems to indicate that you are calculating a time difference for the total column.我认为这里的问题是您使用的 Pydantic 模型期望time对象类型,而它应该期望timedelta类型,因为您的 sql 语句似乎表明您正在计算total列的时间差。

So you Pydantic schemas.py file should read:所以你 Pydantic schemas.py 文件应该是:

from typing import List, Optional
from datetime import date, datetime, timedelta

from pydantic import BaseModel
from . import models

...


class TimeSheetRange(BaseModel):
    user_id: int
    start: date
    total: timedelta

    class Config:
        orm_mode = True

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM