690e68a542
Funciones CRUD completas para BigQuery: auth, datasets, tables, queries, jobs, routines, load/export. Tipo BQClient como wrapper del SDK oficial.
135 lines
4.2 KiB
Python
135 lines
4.2 KiB
Python
"""Gestion de routines (UDFs y stored procedures) en Google BigQuery."""
|
|
|
|
from .client import BQClient
|
|
from google.cloud import bigquery
|
|
|
|
|
|
def bq_create_routine(
|
|
client: BQClient,
|
|
dataset_id: str,
|
|
routine_id: str,
|
|
body: str,
|
|
routine_type: str = "SCALAR_FUNCTION",
|
|
language: str = "SQL",
|
|
arguments: list[dict] | None = None,
|
|
return_type: str = "",
|
|
description: str = "",
|
|
) -> dict:
|
|
"""Crea una routine (UDF o stored procedure) en BigQuery.
|
|
|
|
Args:
|
|
client: Cliente autenticado.
|
|
dataset_id: ID del dataset donde crear la routine.
|
|
routine_id: ID/nombre de la routine.
|
|
body: Cuerpo de la routine (SQL, JavaScript o Python).
|
|
routine_type: Tipo: "SCALAR_FUNCTION", "TABLE_VALUED_FUNCTION", "PROCEDURE".
|
|
language: Lenguaje: "SQL", "JAVASCRIPT", "PYTHON".
|
|
arguments: Lista de argumentos, cada uno: {"name": "x", "data_type": "STRING"}.
|
|
return_type: Tipo de retorno para funciones (ej: "STRING", "INT64"). No aplica a procedures.
|
|
description: Descripcion opcional.
|
|
|
|
Returns:
|
|
Dict con: routine_id, dataset_id, project, routine_type, language, body, created, modified.
|
|
|
|
Raises:
|
|
google.api_core.exceptions.Conflict: Si la routine ya existe.
|
|
|
|
Example:
|
|
>>> bq_create_routine(client, "analytics", "double_value",
|
|
... body="x * 2",
|
|
... arguments=[{"name": "x", "data_type": "INT64"}],
|
|
... return_type="INT64")
|
|
"""
|
|
ref = bigquery.RoutineReference.from_string(
|
|
f"{client.project_id}.{dataset_id}.{routine_id}"
|
|
)
|
|
routine = bigquery.Routine(ref)
|
|
routine.type_ = routine_type
|
|
routine.language = language
|
|
routine.body = body
|
|
if description:
|
|
routine.description = description
|
|
if arguments:
|
|
routine.arguments = [
|
|
bigquery.RoutineArgument(
|
|
name=arg["name"],
|
|
data_type=bigquery.StandardSqlDataType(
|
|
type_kind=getattr(
|
|
bigquery.StandardSqlTypeNames, arg["data_type"]
|
|
)
|
|
),
|
|
)
|
|
for arg in arguments
|
|
]
|
|
if return_type:
|
|
routine.return_type = bigquery.StandardSqlDataType(
|
|
type_kind=getattr(bigquery.StandardSqlTypeNames, return_type)
|
|
)
|
|
created = client._client.create_routine(routine)
|
|
return _routine_to_dict(created)
|
|
|
|
|
|
def bq_list_routines(client: BQClient, dataset_id: str) -> list[dict]:
|
|
"""Lista routines de un dataset.
|
|
|
|
Args:
|
|
client: Cliente autenticado.
|
|
dataset_id: ID del dataset.
|
|
|
|
Returns:
|
|
Lista de dicts con: routine_id, dataset_id, project, routine_type, language.
|
|
|
|
Example:
|
|
>>> routines = bq_list_routines(client, "analytics")
|
|
>>> for r in routines:
|
|
... print(r["routine_id"], r["routine_type"], r["language"])
|
|
"""
|
|
ref = f"{client.project_id}.{dataset_id}"
|
|
return [
|
|
{
|
|
"routine_id": r.routine_id,
|
|
"dataset_id": dataset_id,
|
|
"project": client.project_id,
|
|
"routine_type": r.type_,
|
|
"language": r.language,
|
|
}
|
|
for r in client._client.list_routines(ref)
|
|
]
|
|
|
|
|
|
def bq_delete_routine(
|
|
client: BQClient,
|
|
dataset_id: str,
|
|
routine_id: str,
|
|
) -> None:
|
|
"""Elimina una routine.
|
|
|
|
Args:
|
|
client: Cliente autenticado.
|
|
dataset_id: ID del dataset.
|
|
routine_id: ID de la routine a eliminar.
|
|
|
|
Raises:
|
|
google.api_core.exceptions.NotFound: Si la routine no existe.
|
|
|
|
Example:
|
|
>>> bq_delete_routine(client, "analytics", "double_value")
|
|
"""
|
|
ref = f"{client.project_id}.{dataset_id}.{routine_id}"
|
|
client._client.delete_routine(ref)
|
|
|
|
|
|
def _routine_to_dict(routine) -> dict:
|
|
"""Convierte un objeto Routine del SDK a dict plano."""
|
|
return {
|
|
"routine_id": routine.routine_id,
|
|
"dataset_id": routine.dataset_id,
|
|
"project": routine.project,
|
|
"routine_type": routine.type_,
|
|
"language": routine.language,
|
|
"body": routine.body,
|
|
"description": routine.description or "",
|
|
"created": routine.created.isoformat() if routine.created else None,
|
|
"modified": routine.modified.isoformat() if routine.modified else None,
|
|
}
|