tortoise / tortoise-orm

Familiar asyncio ORM for python, built with relations in mind
https://tortoise.github.io
Apache License 2.0
4.38k stars 356 forks source link

Bug: Pydantic 2.7 broke `pydantic_model_creator` #1586

Closed jamesbraza closed 2 months ago

jamesbraza commented 2 months ago

Describe the bug

Pydantic 2.7.0 (released today) broke pydantic_model_creator, it now throws this error:

Meta
  Extra inputs are not permitted [type=extra_forbidden, input_value=<class 'tortoise.models.Model.Meta'>, input_type=type]
    For further information visit https://errors.pydantic.dev/2.7/v/extra_forbidden

To Reproduce

I am using tortoise-orm==0.20.0 and Python 3.12.2. The below code runs with Pydantic 2.6.4, but not with Pydantic 2.7.0:

import asyncio
from unittest.mock import patch

from tortoise import Model, fields
from tortoise.contrib.pydantic.creator import pydantic_model_creator

class SomeDBModel(Model):
    id = fields.CharField(max_length=10, pk=True)
    foo = fields.IntField(default=1)

SomeModel = pydantic_model_creator(SomeDBModel, name="UserModel")
db_model = SomeDBModel(id="1")
with patch.object(db_model, "fetch_related"):
    model = asyncio.run(SomeModel.from_tortoise_orm(db_model))

Expected behavior

pydantic_model_creator to work with Pydantic 2.7

Additional context

N/a

0xdbff commented 2 months ago

Examples from the website are failing with pydantic 2.7, maybe this should be documented?

tan-wood commented 2 months ago

Has anyone found any work arounds in the mean time?

abondar commented 2 months ago

Yeah, I can confirm that bug is real

Problem seems to be that something changed in processing of models in pydantic, and it recognises Model.Meta as attribute and sends it to validation, which fails, because models generated by pydantic_model_creator has extra="forbid", not allowing extra attributes.

As very hacky workaround - you can run

from tortoise.contrib.pydantic import PydanticModel

PydanticModel.model_config["extra"] = "ignore"

somewhere on init of your code, before pydantic_model_creator

I also created issue with pydantic - https://github.com/pydantic/pydantic/issues/9300 - may be they will be able to provide some insights into why this is happening and how can we bypass that without switching from extra="forbid"

abondar commented 2 months ago

They confirmed that it is indeed pydantic bug, which will be fixed in 2.7.1, which should be released today

I'll close issue once I confirm that fix works

abondar commented 2 months ago

Yeah, fixed with pydantic 2.7.1

jamesbraza commented 2 months ago

Thanks for making that issue @abondar and ensuring the community is back up and running. What do you think of:

So taking this https://github.com/tortoise/tortoise-orm/blob/0.20.0/pyproject.toml#L75 to something like pydantic = "^2.0,!=2.7.0"

abondar commented 2 months ago

Sounds good, right now I am working on some clean up and rooting out one elusive bug, when I will be ready to make release I'll try to incorporate this extra