Big Query Estado de trabajo hecho antes de que termine la consulta
Tengo una aplicación scala que crea una tabla tsv usando BigQuery. Cuando un usuario intenta acceder a los datos que quiero devolverlo si el trabajo de consulta está terminado, de lo contrario diles que sigue funcionando.
Mi creación de trabajo de consulta se ve así:
bigQuery.create(
JobInfo.of(
QueryJobConfiguration
.newBuilder(mySql)
.setAllowLargeResults(true)
.setDestinationTable(TableId.of("MyReports", s"${tableName}_$random".replace("-", "_")))
.setWriteDisposition(JobInfo.WriteDisposition.WRITE_TRUNCATE)
.setCreateDisposition(JobInfo.CreateDisposition.CREATE_IF_NEEDED)
.setUseLegacySql(false)
.build()
)
)
y el método para obtener los datos se ve así:
override def getData(jobId: String): IO[Either[Throwable, String]] = {
bigQueryService.getMyJob(jobId).map {
case Right(None) | Right(Some(null)) => Right("Data not found, check provided job name")
case Right(Some(r)) =>
if (r.isDone) {
Try(r.getQueryResults()
.iterateAll()
.asScala
.map(_.asScala.map(_.getValue.toString).mkString("\t"))
.mkString("\n")
).toEither
} else {
Right(s"Job not completed, current status is ${r.getStatus.getState.toString}")
}
case Left(err: Throwable) => Left(err)
}
}
Donde estoy usando Cats Effect IO para evaluar al final de la computación. Mi problema es que getQueryResults
método en un trabajo se detiene hasta que la consulta está terminada. Intento prevenir esto comprobando otro método en un empleo de barbacoa: isDone
. Por alguna razón en mis pruebas, isDone
vuelve verdad antes de que la consulta haya terminado. Lo veo yo mismo al revisar la consola BigQuery. Esto resulta en la solicitud de un usuario siempre estancado hasta que la consulta termine, en lugar de devolver un mensaje como se desee.
¿Cómo se puede completar un trabajo mientras la consulta sigue funcionando? ¿Me estoy perdiendo alguna distinción entre empleos y consultas? ¿O hay algo más que he perdido? Gracias por cualquier sugerencia que pueda tener.
Pregunta hecha hace 3 años, 4 meses, 29 días - Por quantumcoder403a
3 Respuestas:
-
jobs.getQueryResults
tiene una opcióntimeoutMs
parámetro que gobierna su colgante GET semantics. Espera la terminación del trabajo hasta ese intervalo especificado o 10 segundos si no se especifica. Si el trabajo está completo regresa inmediatamente independientemente.Si establece el tiempo a cero, devolverá la respuesta inmediatamente, y puede comprobar las estadísticas de resultados para ver si el trabajo está completo. Si es así, la respuesta también debe contener el esquema y la primera página de filas de datos.
Información adicional de la referencia REST: https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/getQueryResults
Respondida el Dec 16, 2020 a las 17:02 - por codecrusader
Votos positivos: 0 | Votos negativos: 0 -
El problema que estás experimentando se debe a que estás verificando el estado del trabajo en BigQuery en lugar del estado de la propia consulta. Un trabajo en BigQuery puede contener múltiples tareas, como la creación de tablas, exportación de resultados, etc., y una de esas tareas es la consulta en sí.
Para comprobar el estado de la consulta en lugar del estado general del trabajo, puedes utilizar el método
getState
en la consulta en sí. Aquí te dejo un ejemplo de cómo podrías modificar tu código para verificar el estado de la consulta en lugar del estado del trabajo en general:scala override def getData(jobId: String): IO[Either[Throwable, String]] = { bigQueryService.getMyJob(jobId).map { case Right(None) | Right(Some(null)) => Right("Data not found, check provided job name") case Right(Some(job)) => val queryJob = bigQuery.getJob(job.getJobId) val queryJobStatus = queryJob.getStatus if (queryJobStatus.getState == QueryJobConfiguration.State.DONE) { val queryResults = queryJob.getQueryResults Try(queryResults.iterateAll() .asScala .map(_.asScala.map(_.getValue.toString).mkString("\t")) .mkString("\n") ).toEither } else { Right(s"Query not completed, current status is ${queryJobStatus.getState.toString}") } case Left(err: Throwable) => Left(err) } }
En este código, recuperas el objeto
QueryJob
a partir del trabajo general en BigQuery y luego verificas el estado de la consulta usandogetState
. Esto te permitirá saber si la consulta está completada o no, en lugar del estado general del trabajo.Espero que esta modificación te ayude a obtener el comportamiento deseado en tu aplicación. ¡Déjame saber si tienes alguna otra pregunta!
Respondida el Dec 17, 2020 a las 16:59 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Distinción entre trabajos y consultas
Un trabajo de BigQuery es un contenedor que puede contener múltiples consultas. Una consulta es una operación específica que se ejecuta dentro de un trabajo.
Estado
isDone
El estado
isDone
de un trabajo indica si todas las consultas dentro del trabajo han finalizado. Sin embargo, no indica si una consulta específica dentro del trabajo ha finalizado.Resolución del problema
Para resolver el problema, debes comprobar el estado de la consulta específica que estás ejecutando. Puedes hacerlo llamando al método
getQueryResults
del trabajo y verificando si el resultado de la consulta está disponible.Aquí tienes un código modificado que comprueba el estado de la consulta:
scala override def getData(jobId: String): IO[Either[Throwable, String]] = { bigQueryService.getMyJob(jobId).map { case Right(None) | Right(Some(null)) => Right("Data not found, check provided job name") case Right(Some(r)) => if (r.isDone) { Try(r.getQueryResults() .iterateAll() .asScala .map(_.asScala.map(_.getValue.toString).mkString("\t")) .mkString("\n") ).toEither } else { // Aquí comprobamos el estado de la consulta específica val query = r.getQueryResults() if (query.getJobComplete) { Try(query .iterateAll() .asScala .map(_.asScala.map(_.getValue.toString).mkString("\t")) .mkString("\n") ).toEither } else { Right(s"Job not completed, current status is ${r.getStatus.getState.toString}") } } case Left(err: Throwable) => Left(err) } }
Este código comprueba primero el estado del trabajo. Si el trabajo está hecho, comprueba el estado de la consulta específica mediante el método
getJobComplete
deQueryResults
. Si la consulta está completa, devuelve los resultados. Si no, devuelve un mensaje que indica que la consulta aún está ejecutándose.Respondida el Dec 17, 2020 a las 17:02 - por Gemini
Votos positivos: 0 | Votos negativos: 0