tortoise / tortoise/tortoise-orm

fields.TimeDeltaField in pydantic_model_creator raise Input should be None [type=none_required, input_value=datetime.timedelta(second...104, microseconds=48382), input_type=timedelta]

Open
#1,462 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
5.6k
Forks
516
Avg merge
2d 21h
Merged PRs (30d)
9

Description

Describe the bug
with
tortoise-orm==0.20.0
pydantic==2.2.1

code like:

class Task(Model):
        usage_time = fields.TimeDeltaField(null=True, blank=True, description='usgae')

class TaskListSchema(pydantic_model_creator(Task, name='TaskListSchema', exclude=('usage_time',))):
    pass

TaskListSchema.from_orm(task).dict()

will get error:

Traceback (most recent call last):
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 404, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 78, in __call__
    return await self.app(scope, receive, send)
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\fastapi\applications.py", line 289, in __call__
    await super().__call__(scope, receive, send)
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\starlette\applications.py", line 122, in __call__
    await self.middleware_stack(scope, receive, send)
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\starlette\middleware\errors.py", line 184, in __call__
    raise exc
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\starlette\middleware\errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\starlette\middleware\base.py", line 108, in __call__
    response = await self.dispatch_func(request, call_next)
  File "D:\python_workspace\AutoTestServer\common\middlewares.py", line 18, in dispatch
    response = await call_next(request)
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\starlette\middleware\base.py", line 84, in call_next
    raise app_exc
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\starlette\middleware\base.py", line 70, in coro
    await self.app(scope, receive_or_disconnect, send_no_error)
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\starlette\middleware\cors.py", line 83, in __call__
    await self.app(scope, receive, send)
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\starlette\middleware\exceptions.py", line 79, in __call__
    raise exc
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\starlette\middleware\exceptions.py", line 68, in __call__
    await self.app(scope, receive, sender)
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 20, in __call__
    raise e
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 17, in __call__
    await self.app(scope, receive, send)
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\starlette\routing.py", line 718, in __call__
    await route.handle(scope, receive, send)
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\starlette\routing.py", line 276, in handle
    await self.app(scope, receive, send)
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\starlette\routing.py", line 66, in app
    response = await func(request)
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\fastapi\routing.py", line 273, in app
    raw_response = await run_endpoint_function(
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\fastapi\routing.py", line 190, in run_endpoint_function
    return await dependant.call(**values)
  File "D:\python_workspace\AutoTestServer\task\views.py", line 232, in task_list
    data = [TaskListSchema.from_orm(task).model_dump() for task in queryset]
  File "D:\python_workspace\AutoTestServer\task\views.py", line 232, in <listcomp>
    data = [TaskListSchema.from_orm(task).model_dump() for task in queryset]
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\typing_extensions.py", line 2562, in wrapper
    return __arg(*args, **kwargs)
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\pydantic\main.py", line 1066, in from_orm
    return cls.model_validate(obj)
  File "D:\python_workspace\AutoTestServer\venv\lib\site-packages\pydantic\main.py", line 496, in model_validate
    return cls.__pydantic_validator__.validate_python(
pydantic_core._pydantic_core.ValidationError: 1 validation error for TaskListSchema
usage_time
  Input should be None [type=none_required, input_value=datetime.timedelta(second...104, microseconds=48382), input_type=timedelta]
    For further information visit https://errors.pydantic.dev/2.2/v/none_required

To Reproduce
print TaskListSchema will get

{
    "additionalProperties": false,
    "properties": {
        "usage_time": {
            "description": "\u4efb\u52a1\u8017\u65f6",
            "nullable": true,
            "title": "Usage Time",
            "type": "null"
        }
    },
    "required": [
        "usage_time"
    ],
    "title": "TaskListSchema",
    "type": "object"
}

when i use
tortoise-orm==0.19.2
pydantic==1.10.2

print TaskListSchema will get

{
    "title": "TaskListSchema",
    "description": "\u81ea\u52a8\u5316\u4efb\u52a1",
    "type": "object",
    "properties": {
        "usage_time": {
            "title": "Usage Time",
            "description": "\u4efb\u52a1\u8017\u65f6",
            "nullable": true,
            "type": "number",
            "format": "time-delta"
        }
    },
    "additionalProperties": false
}

this schema will work! Is there something change in pydantic_model_creator when handle fields.TimeDeltaField ?
Expected behavior
fields.TimeDeltaField in pydantic_model_creator works good

Additional context
Add any other context about the problem here.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with tortoise-orm 0.20.0 and pydantic 2.2.1 using the provided TimeDeltaField and pydantic_model_creator example. Inspect how pydantic_model_creator handles fields.TimeDeltaField, comparing the generated schema with the working older versions. Done means the generated field accepts a datetime.timedelta value and produces the expected non-null time-delta schema.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.