Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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] #1462

Open
yinkh opened this issue Aug 23, 2023 · 6 comments · May be fixed by #1463

Comments

@yinkh
Copy link

yinkh commented Aug 23, 2023

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.

@yinkh
Copy link
Author

yinkh commented Aug 23, 2023

pydantic 1.10.12
tortoise-orm 0.19.2
works!

pydantic 1.10.12
tortoise-orm 0.19.3
not works!

@long2ice
Copy link
Member

Can you give a full example? I can't reproduce.

@yinkh
Copy link
Author

yinkh commented Aug 23, 2023

aiomysql 0.2.0
pydantic 1.10.12
tortoise-orm 0.19.3 not work
tortoise-orm 0.19.2 work
main.py

import asyncio
import datetime

from tortoise import Tortoise
from tortoise.contrib.pydantic import pydantic_model_creator
from tortoise import Model
from tortoise import fields

DATABASE_URI = f"mysql://root:root@127.0.0.1:3306/autotest?charset=utf8&maxsize=100&connect_timeout=30"


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

    class Meta:
        table = "demo"
        ordering = ["-id"]


DemoSchema = pydantic_model_creator(Demo, name='DemoSchema', include=('usage_time',))


async def demo_example():
    print('demo_example')
    await Tortoise.init(db_url=DATABASE_URI, modules={"models": ["__main__"]})
    await Tortoise.generate_schemas()

    start_time = datetime.datetime.now() - datetime.timedelta(hours=1)
    end_time = datetime.datetime.now()
    usage = end_time - start_time
    demo = await Demo.create(usage_time=usage)
    a = DemoSchema.from_orm(demo).dict()
    print(a)


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    # Blocking call which returns when the display_date() coroutine is done
    loop.run_until_complete(demo_example())
    loop.close()

@yinkh
Copy link
Author

yinkh commented Aug 23, 2023

after digging,
creator.py:
Line 261 model_description value in 0.19.2:
0 19 2
in 0.19.3:
19 3

the reason is TimeDeltaField is no longer extend datetime.timedelta, any idea why delete this extend?:
image

@yinkh
Copy link
Author

yinkh commented Aug 23, 2023

image

yinkh pushed a commit to yinkh/tortoise-orm that referenced this issue Aug 23, 2023
@yinkh yinkh linked a pull request Aug 23, 2023 that will close this issue
@yinkh
Copy link
Author

yinkh commented Aug 23, 2023

When create pr, i try to run test inside my desktop,but this error is raise, and Contribution Guide not explain for this.:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants