from google.cloud import bigquery from typing import Generator, List, Dict import os os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "rag-datasets-reader-sa-key.json" def consultar_bigquery_paginado( sql_query: str, page_size: int = 1000, project_id: str | None = None ) -> Generator[List[Dict], None, None]: """ Ejecuta una consulta SQL de BigQuery y devuelve los resultados paginados. Limpia el texto SQL automáticamente antes de ejecutarlo. Args: sql_query (str): Texto SQL (puede incluir espacios o punto y coma al final). page_size (int): Número de filas por página. project_id (str | None): ID del proyecto GCP (opcional si está configurado el entorno). Yields: list[dict]: Página de resultados (cada fila convertida a dict). """ # 🧹 Limpieza del texto SQL cleaned_query = ( sql_query.strip() # elimina espacios y saltos al inicio y fin .removeprefix("```sql").removeprefix("```").removesuffix("```") # limpia delimitadores markdown si los hay .strip() # vuelve a limpiar por si quedaron espacios ) # Quita el punto y coma final si lo tiene if cleaned_query.endswith(";"): cleaned_query = cleaned_query[:-1].strip() # Inicializa el cliente client = bigquery.Client(project=project_id) # Ejecuta la consulta query_job = client.query(cleaned_query) # Devuelve resultados paginados iterator = query_job.result(page_size=page_size) for page in iterator.pages: yield [dict(row) for row in page] if __name__ == "__main__": resultado = consultar_bigquery_paginado("""```sql SELECT Productos___Producto_NavId__description AS producto, Centros___Centro_NavId__name AS region, SUM(cantidad) AS total_vendido, SUM(cantidad * precioUnitario) AS ingreso_total FROM `autingo-159109.rag_datasets.Objeto_Ventas` WHERE Fecha >= DATE_SUB(CURRENT_DATE(), INTERVAL 3 MONTH) GROUP BY producto, region ORDER BY total_vendido DESC; ```""") for pagina in resultado: for fila in pagina: print(fila) print("----- Fin de página -----")