fastapi-crudrouter
fastapi-crudrouter copied to clipboard
Pydantic V2 incompatibility: FieldInfo object does not have the attribute 'type_'
Issue Statement
Incompatible with pydantic v2. Unable to start containerized uvicorn due to AttributeError. This occurs because pydantic's FieldInfo object does not have the attribute 'type_' Please see: pydantic.fields.FieldInfo
This can be observed by adding the following line on startup:
print(Potato.__fields__)
The output follows:
{'thickness': FieldInfo(annotation=float, required=True), 'mass': FieldInfo(annotation=float, required=True), 'color': FieldInfo(annotation=str, required=True), 'type': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=int, required=True)}
Code
from sqlalchemy import Column, String, Float, Integer
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from pydantic import BaseModel
from fastapi import FastAPI
from fastapi_crudrouter import SQLAlchemyCRUDRouter
app = FastAPI()
engine = create_engine(
"sqlite:///./app.db",
connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(
autocommit=False,
autoflush=False,
bind=engine
)
Base = declarative_base()
def get_db():
session = SessionLocal()
try:
yield session
session.commit()
finally:
session.close()
class PotatoCreate(BaseModel):
thickness: float
mass: float
color: str
type: str
class Potato(PotatoCreate):
id: int
class Config:
orm_mode = True
class PotatoModel(Base):
__tablename__ = 'potatoes'
id = Column(Integer, primary_key=True, index=True)
thickness = Column(Float)
mass = Column(Float)
color = Column(String)
type = Column(String)
Base.metadata.create_all(bind=engine)
print(Potato.__fields__)
router = SQLAlchemyCRUDRouter(
schema=Potato,
create_schema=PotatoCreate,
db_model=PotatoModel,
db=get_db,
prefix='potato'
)
app.include_router(router)
Error
>| File "/app/src/main.py", line 63, in <module>
>| router = SQLAlchemyCRUDRouter(
>| File "/usr/local/lib/python3.8/site-packages/fastapi_crudrouter/core/sqlalchemy.py", line 51, in __init__
>| self._pk_type: type = _utils.get_pk_type(schema, self._pk)
>| File "/usr/local/lib/python3.8/site-packages/fastapi_crudrouter/core/_utils.py", line 17, in get_pk_type
>| return schema.__fields__[pk_field].type_
>| AttributeError: 'FieldInfo' object has no attribute 'type_'
I got this issue. And my workaround is patch two methods:
patch_crudrouter
def get_pk_type_patch(schema: Type[PYDANTIC_SCHEMA], pk_field: str) -> Any:
try:
return schema.__fields__[pk_field].annotation
except KeyError:
return int
from pydantic import create_model
def schema_factory_patch(
schema_cls: Type[T], pk_field_name: str = "id", name: str = "Create"
) -> Type[T]:
"""
Is used to create a CreateSchema which does not contain pk
"""
fields = {
name: (f.annotation, ...)
for name, f in schema_cls.__fields__.items()
if name != pk_field_name
}
name = schema_cls.__name__ + name
schema: Type[T] = create_model(__model_name=name, **fields) # type: ignore
return schema
Injection
import fastapi_crudrouter
fastapi_crudrouter.core._utils.get_pk_type = get_pk_type_patch
fastapi_crudrouter.core._utils.schema_factory = schema_factory_patch
fastapi_crudrouter.core._base.schema_factory = schema_factory_patch
it works
import fastapi_crudrouter
fastapi_crudrouter.core._utils.get_pk_type = get_pk_type_patch
fastapi_crudrouter.core._utils.schema_factory = schema_factory_patch
fastapi_crudrouter.core._base.schema_factory = schema_factory_patch
It helps: https://github.com/awtkns/fastapi-crudrouter/issues/189#issuecomment-1779496250 Thanks a lot
I took this part for my diploma) from pydantic import create_model def schema_factory_patch( schema_cls: Type[T], pk_field_name: str = "id", name: str = "Create" ) -> Type[T]: """ Is used to create a CreateSchema which does not contain pk """
fields = {
name: (f.annotation, ...)
for name, f in schema_cls.__fields__.items()
if name != pk_field_name
}
name = schema_cls.__name__ + name
schema: Type[T] = create_model(__model_name=name, **fields) # type: ignore
return schema