python-3.xfastapitortoise-orm

FastAPI + Tortoise ORM got KeyError: '__module__' on pydantic_model_creator


I am very new in Tortoise ORM. I started with a very simple application modified from Tortoise-ORM FastAPI integration and I got errors.

requirements.txt

fastapi==0.100.0
tortoise-orm==0.19.3
uvicorn==0.22.0

directory structure:

app
   __init__.py
   main.py
   Pipfile
   Pipfile.lock
   requirements.txt

main.py

from fastapi import FastAPI
from tortoise import fields, models, Tortoise
from tortoise.contrib.pydantic import pydantic_model_creator
from tortoise.contrib.fastapi import register_tortoise

app = FastAPI()

class User(models.Model):
   id = fields.IntField(pk=True)
   username = fields.CharField(100)
   email = fields.CharField(100)
   password_hash = fields.CharField(150)

   class PydanticMeta:
      exclude = ["password_hash"]

Tortoise.init_models(["main"], "models") # <-- errors occur with/without this line

# these two lines are triggering the errors
User_Pydantic = pydantic_model_creator(User, name="User")
UserIn_Pydantic = pydantic_model_creator(User, name="UserIn", exclude_readonly=True)

@app.get("/")
async def home():
   return {"hello": "world"}

# errors occur with/without tortoise registration
register_tortoise(
    app,
    db_url="sqlite://database.sqlite3",
    modules={"models": ["main"]},
    generate_schemas=True,
    add_exception_handlers=True
)

When I run the application uvicorn main:app --reload, I got these bunch of errors:

/xxx/xxx/.local/share/virtualenvs/app-MrBmwYgz/lib/python3.7/site-packages/pydantic/_internal/_config.py:261: UserWarning: Valid config keys have changed in V2:
* 'orm_mode' has been renamed to 'from_attributes'
  warnings.warn(message, UserWarning)
/xxx/xxx/.local/share/virtualenvs/app-MrBmwYgz/lib/python3.7/site-packages/pydantic/_internal/_config.py:261: UserWarning: Valid config keys have changed in V2:
* 'orm_mode' has been renamed to 'from_attributes'
* 'fields' has been removed
  warnings.warn(message, UserWarning)
Process SpawnProcess-1:
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
    self.run()
  File "/usr/local/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "/xxx/xxx/.local/share/virtualenvs/app-MrBmwYgz/lib/python3.7/site-packages/uvicorn/_subprocess.py", line 76, in subprocess_started
    target(sockets=sockets)
  File "/xxx/xxx/.local/share/virtualenvs/app-MrBmwYgz/lib/python3.7/site-packages/uvicorn/server.py", line 61, in run
    return asyncio.run(self.serve(sockets=sockets))
  File "/usr/local/lib/python3.7/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "uvloop/loop.pyx", line 1517, in uvloop.loop.Loop.run_until_complete
  File "/xxx/xxx/.local/share/virtualenvs/app-MrBmwYgz/lib/python3.7/site-packages/uvicorn/server.py", line 68, in serve
    config.load()
  File "/xxx/xxx/.local/share/virtualenvs/app-MrBmwYgz/lib/python3.7/site-packages/uvicorn/config.py", line 473, in load
    self.loaded_app = import_from_string(self.app)
  File "/xxx/xxx/.local/share/virtualenvs/app-MrBmwYgz/lib/python3.7/site-packages/uvicorn/importer.py", line 21, in import_from_string
    module = importlib.import_module(module_str)
  File "/usr/local/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/xxx/xxx/app/main.py", line 21, in <module>
    User_Pydantic = pydantic_model_creator(User, name="User")
  File "/xxx/xxx/.local/share/virtualenvs/app-MrBmwYgz/lib/python3.7/site-packages/tortoise/contrib/pydantic/creator.py", line 437, in pydantic_model_creator
    model = cast(Type[PydanticModel], type(_name, (PydanticModel,), properties))
  File "/xxx/xxx/.local/share/virtualenvs/app-MrBmwYgz/lib/python3.7/site-packages/pydantic/_internal/_model_construction.py", line 96, in __new__
    namespace, config_wrapper.ignored_types, class_vars, base_field_names
  File "/xxx/xxx/.local/share/virtualenvs/app-MrBmwYgz/lib/python3.7/site-packages/pydantic/_internal/_model_construction.py", line 287, in inspect_namespace
    and value.__module__ == namespace['__module__']
KeyError: '__module__'

I also try to separate orm and schema, but I faced same errors. I am curious about this pydantic_model_creator which is triggering the error.

Thank you very much for the help and advice.


Solution

  • From your errors, I suspect that Tortoise is not yet compativle with Pydantic V2 that was released the other week. Try adding pydantic<2.0.0 to your requirements.txt file and run pip install -r requirements.txt again.