Jestem dość nowy w tym ramie, ale pracuję nad aplikacją do wyświetlenia (API) dla małej firmy.

Problem, który mam, to po wybraniu wartości czasu z MySQL dostałem następujący błąd w module 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)

Wypróbowałem wiele obejścia, aby uzyskać czas na ciąg z MySQL za pomocą to_char(), który również nie powiódł się, ale raczej chcę wiedzieć, co jest tutaj, tak jak chciałbym użyć czasu typu danych ...

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

I zapytanie SQL, które jest budowane z wynikiem:

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 |
+-------------------+------------+----------+

Czy coś jest nie tak z DataType time lub brakuje mi czegoś naprawdę głupiego?

1
comlink 20 październik 2020, 00:04

1 odpowiedź

Najlepsza odpowiedź

Myślę, że kwestia jest tutaj, że używany model Pydantic spodziewa się typu obiektu time, gdy należy spodziewać się typu timedelta, gdy wydaje się wyciąg SQL wskazujący, że obliczysz różnicę czasu Dla kolumny total.

Więc pydantic schemas.py Plik powinien przeczytać:

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
1
TheDataFox 20 październik 2020, 09:29