AttributeError: 'int' object has no attribute '_saved_in_db' , Fastifi , Tortoise-orm

68 Views Asked by At

I m using fastapi , tortoise-orm and pydantic , everything works file except the Post method whiich contain foreign fild.

I get the error saying AttributeError: 'int' object has no attribute '_saved_in_db'

for database I am using elephantSql(postgres)

Table model

from tortoise import fields
from tortoise.models import Model


class Table(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=20)

Sale Model

from tortoise import fields
from tortoise.models import Model
from models.Table import Table


class Sale(Model): 
    id = fields.IntField(pk=True)
    discount_amount = fields.FloatField(default=0)
    is_draft = fields.BooleanField(default=True)
    table = fields.ForeignKeyField(
        "models.Table", related_name='sales', on_delete=fields.NO_ACTION)
    table: fields.ForeignKeyRelation[Table] = fields.ForeignKeyField(
        "models.Table", related_name="sales")

Table Schema

from typing import Optional
from pydantic import BaseModel, ValidationError


class TableIn(BaseModel):
    name: str


class TableOut(BaseModel):
    id: int
    name: str


class TableQueryParams(BaseModel):
    page: Optional[int] = 1
    limit: Optional[int] = 5
    name: Optional[str] = None

Sale Schema

from typing import Optional
from pydantic import BaseModel
from models.Table import Table


class SaleIn(BaseModel):
    discount_amount: float
    is_draft: bool
    table: int


class SaleOut(BaseModel):
    id: int
    discount_amount: float
    is_draft: bool
    table: int


class SaleQueryParams(BaseModel):
    page: Optional[int] = 1
    limit: Optional[int] = 5
    table: Optional[int] = None

Sale Route (Controller)

from fastapi import APIRouter, Depends
from typing import List
from models.Sale import Sale
from schemas.saleSchema import SaleIn, SaleOut, SaleQueryParams
saleRouter = APIRouter()


@saleRouter.post("", response_model=SaleOut)
async def create(sale: SaleIn) -> SaleOut:
    # new_sale = await Sale.create(**sale.model_dump())
    # return new_sale

    new_sale = await Sale.create(discount_amount=sale.discount_amount, is_draft=sale.is_draft, table=sale.table)
    saved_sale=new_sale.save()
    return saved_sale


@saleRouter.get("", response_model=List[SaleOut])
async def get_all(query_params: SaleQueryParams = Depends()) -> List[SaleOut]:
    offset = (query_params.page - 1) * query_params.limit
    query = Sale.all()

    if query_params.table:
        query = query.filter(table__icontains=query_params.name)

    sales = await query.offset(offset).limit(query_params.limit)
    return list(sales)

Error:

INFO:     127.0.0.1:58776 - "POST /sales HTTP/1.1" 500 Internal Server Error
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\uvicorn\protocols\http\httptools_impl.py", line 426, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\uvicorn\middleware\proxy_headers.py", line 84, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\fastapi\applications.py", line 292, in __call__
    await super().__call__(scope, receive, send)
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\starlette\applications.py", line 122, in __call__
    await self.middleware_stack(scope, receive, send)
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\starlette\middleware\errors.py", line 184, in __call__
    raise exc
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\starlette\middleware\errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\starlette\middleware\exceptions.py", line 79, in __call__
    raise exc
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\starlette\middleware\exceptions.py", line 68, in __call__
    await self.app(scope, receive, sender)
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 20, in __call__
    raise e
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 17, in __call__
    await self.app(scope, receive, send)
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\starlette\routing.py", line 718, in __call__
    await route.handle(scope, receive, send)
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\starlette\routing.py", line 276, in handle
    await self.app(scope, receive, send)
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\starlette\routing.py", line 66, in app
    response = await func(request)
               ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\fastapi\routing.py", line 273, in app
    raw_response = await run_endpoint_function(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\fastapi\routing.py", line 190, in run_endpoint_function
    return await dependant.call(**values)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\loken\Desktop\test\routes\saleRoute.py", line 13, in create
    new_sale = await Sale.create(discount_amount=sale.discount_amount, is_draft=sale.is_draft, table=sale.table)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\tortoise\models.py", line 1133, in create
    instance = cls(**kwargs)
               ^^^^^^^^^^^^^
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\tortoise\models.py", line 672, in __init__
    for key in meta.fields.difference(self._set_kwargs(kwargs)):
                                      ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\loken\AppData\Local\Programs\Python\Python311\Lib\site-packages\tortoise\models.py", line 687, in _set_kwargs
    if value and not value._saved_in_db:
                     ^^^^^^^^^^^^^^^^^^
AttributeError: 'int' object has no attribute '_saved_in_db'

Only the post operation which include foreign key , throws this error

0

There are 0 best solutions below