快速 API - MySQL - SQLAlchemy:在 Pydantic 模型中获取验证错误 'Invalid type'
Fast API - MySQL - SQLAlchemy: Get ValidationError 'Invalid type' in Pydantic Model
我对这个框架相当陌生,但我正在为一家小公司开发时间表应用程序 (API)。
我遇到的问题是,当我 select 来自 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)
我已经尝试了很多解决方法来获得从 mysql 到 to_char()
的字符串的时间,但也失败了,但我更想知道这里的问题是什么,因为我想使用数据类型时间...
schemas.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
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
而构建的 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 |
+-------------------+------------+----------+
数据类型有问题吗 time
还是我遗漏了一些非常愚蠢的东西?
我认为这里的问题是您正在使用的 Pydantic 模型需要一个 time
对象类型,而它应该像您的 sql 语句那样需要一个 timedelta
类型表示您正在计算 total
列的时间差。
所以你的 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
我对这个框架相当陌生,但我正在为一家小公司开发时间表应用程序 (API)。
我遇到的问题是,当我 select 来自 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)
我已经尝试了很多解决方法来获得从 mysql 到 to_char()
的字符串的时间,但也失败了,但我更想知道这里的问题是什么,因为我想使用数据类型时间...
schemas.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
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
而构建的 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 |
+-------------------+------------+----------+
数据类型有问题吗 time
还是我遗漏了一些非常愚蠢的东西?
我认为这里的问题是您正在使用的 Pydantic 模型需要一个 time
对象类型,而它应该像您的 sql 语句那样需要一个 timedelta
类型表示您正在计算 total
列的时间差。
所以你的 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