pythongraphqlfastapistrawberry-graphql

Error 'tuple' object has no attribute 'obs - Python GraphQL Strawberry + FastAPI


I'm starting a graphql project where I'm creating an API to get data from an Informix database. I've managed to get everything working but I can't get any results and instead I get the error

'tuple' object has no attribute 'obs

Any help would be appreciated!

This is what I have

[main.py]

from fastapi import FastAPI
from schema import graphql_app 
app = FastAPI() 
app.include_router(graphql_app, prefix='/bitola')

[schema.py]

from typing import Optional, List
import strawberry
import datetime 
from strawberry.fastapi import GraphQLRouter 
from dbfunctions import get_bitola

@strawberry.type
class Bitola: 
    cod_bitola: Optional[int] 
    des_abr_bitola: str 
    des_bitola: str 
    qtd_largura: int 
    data_insercao: datetime.datetime 
    data_alteracao: datetime.datetime 
    obs: str

@strawberry.type
class Query: 
    allBitolas: List[Bitola] = strawberry.field(resolver=get_bitola)

schema = strawberry.Schema(query=Query)
graphql_app = GraphQLRouter(schema, graphiql=True, allow_queries_via_get=False)

[dbfunctions.py]

import jaydebeapi
def get_bitola():
    conn = jaydebeapi.connect("com.informix.jdbc.IfxDriver",
                            "jdbc:informix-sqli://ifxserver:INFORMIXSERVER=ifxdv",
                            ["user", "pass"],
                            "/path/to/jdbcdriver/informix-jdbc-complete-4.50.4.1.jar")
    curs = conn.cursor()
    curs.execute('select * from bitola')
    ldb = curs.fetchall()
    curs.close()
    conn.close()
    return ldb

When testing with

hypercorn main:app

i go to localhost:8000/bitola and input the query

{
  allBitolas {
    obs
  }
}

i get the error message

{
  "data": null,
  "errors": [
    {
      "message": "'tuple' object has no attribute 'obs'",
      "locations": [
        {
          "line": 3,
          "column": 5
        }
      ],
      "path": [
        "allBitolas",
        0,
        "obs"
      ]
    }
  ]
}

and I can't understand why.

TY for all the help and pointers!


Solution

  • The lib i'm using (jaydebeapi), cursor.fetchAll() returns a list of tuples, whereas the resolver needs to return a list of instances of Bitola. So for each member in the list returned from the db call, I need to transform it into an instance.

    So I did and it's working as intendend.

    @dataclass
    class Bitola2:
        cod_bitola: int
        des_abr_bitola: str
        des_bitola: str
        qtd_largura: int
        data_insercao: str
        data_alteracao: str
        obs: str
    
    def TransformTuple(dbrec):
        return Bitola2(cod_bitola=dbrec[0], des_abr_bitola=dbrec[1], des_bitola=dbrec[2], qtd_largura=dbrec[3], data_insercao=dbrec[4], data_alteracao=dbrec[5], obs=dbrec[6])
    

    Answered on Reddit