Soy nuevo en async await y trato de usarlo para obtener una respuesta de un método de consulta SQL db definido en un punto final
@router.get('/queryDAS') async def fetch_das_db(): response = await DASDBData().get_all() logger.info("---ASYNCRONOUS----") return (json.dumps(response))pero todo lo que obtengo es este error: respuesta = esperar DASDBData().get_all() TypeError: la lista de objetos no se puede usar en la expresión 'esperar'
def get_all(self): """Get all new data. @returns: Return list of dictionaries with team information. """ result=[] statement = """SELECT * FROM CAE_APPR_ITEM_RESPONSE WHERE ROWNUM <= 500 """ logger.debug(statement) cur = self.connection.create_connection().cursor() cur.execute(statement) for row in cur: print(row) result.append(row) #return (200,result) return resultPensé que el mensaje "---ASYNCHRONOUS---" se imprimiría primero, ya que el método get_all iría dentro de event_loop, pero tampoco se imprimió.
TL;DR
@router.get('/queryDAS') async def fetch_das_db(): response = DASDBData().get_all() logger.info("---ASYNCRONOUS----") return (json.dumps(await response))
A partir de los comentarios, realmente le sugiero que lea primero cómo funciona async await. Esto es lo que creo que es un buen tutorial sobre async await.
Después de leer el tutorial/explicación, comprenderá que response = await DASDBData().get_all() esperará el resultado de get_all() antes de continuar... comportándose como el código síncrono tradicional.
Ahora, si elimina la palabra clave await , su declaración de impresión se ejecutará antes de que finalice el método, pero también recibirá una advertencia acerca de que no se está esperando su rutina. Esto es similar a comenzar un proyecto, pero nunca terminarlo. La variable de respuesta contendrá la corrutina, una especie de resultado futuro, que aún no existe.
Con esto en mente, puede devolver el resultado mientras lo espera, modificando la última declaración de devolución en return (json.dumps(await response)) . Esto esperará el resultado futuro y lo volcará como una cadena antes de devolverlo.
Si necesita usar el resultado para otras cosas, puede import asyncio y luego usar response = await asyncio.gather(response) para obtener el valor de su respuesta. Esto simplemente esperará a que se ejecute la rutina y devolverá el valor resultante (es decir, la ejecución se bloquea hasta que la función devuelve algo). A continuación, puede hacer lo que quiera con el resultado.
Una nota al margen:
FastAPI convierte automáticamente el valor devuelto a JSON. A menos que esté utilizando un formato especial, le aconsejo que simplemente return await response (la espera puede ser necesaria o no, según el enfoque que utilice).