Docs / Build Workflow

Sources

Sources son el paso uno de la confiabilidad del contenido

Los models dependen de aliases de source. Si el alias, el filename de credentials o la referencia al dataset están mal, cada model, query y visualization construida arriba falla. Configura y valida runtime/sources.runtime.yml antes de escribir un solo model.

Si todavía no creaste tu service account de GCP, haz eso primero. Mira Acceso al Dataset de BigQuery.

Working example: dataset público de BigQuery

Working example usando el dataset público bigquery-public-data.thelook_ecommerce. Copialo como tu punto de partida; reemplaza project_id con tu propio billing project de GCP y credentials_file con el nombre del archivo JSON de tu service account (el archivo que dropeas en secrets/). El dataset es público, así que cualquiera con un service account de BigQuery funcionando lo puede consultar.

sources:
  ecommerce:
    name: The Look Ecommerce
    type: bigquery
    project_id: my-gcp-billing-project
    credentials_file: my-workspace-bq.json
    datasets:
      - bigquery-public-data.thelook_ecommerce

Campo por campo:

  • ecommerce: el alias que van a usar tus models de Malloy. Elige algo corto y estable — cambiarlo después rompe cada model que lo referencia.
  • project_id: el proyecto de GCP que paga el costo de las queries. Este es tu billing project, no necesariamente donde viven los datos.
  • credentials_file: filename plano del JSON de service-account dropeado en la carpeta secrets/ del workspace. Pattern ^[A-Za-z0-9_-][A-Za-z0-9._-]*$ — sin separadores de path, sin punto inicial.
  • datasets: las ubicaciones de dataset que el runtime puede consultar. Acá los datos están en bigquery-public-data, un proyecto distinto al billing — eso es normal y esperado.

Working example: tu propio dataset privado

Cuando los datos viven en tu propio proyecto de GCP, project_id y el proyecto del dataset son el mismo:

sources:
  sales:
    name: Sales Data
    type: bigquery
    project_id: my-company-gcp-project
    credentials_file: my-workspace-bq.json
    datasets:
      - my-company-gcp-project.sales_warehouse

Puedes definir múltiples sources en el mismo archivo:

sources:
  sales:
    name: Sales Data
    type: bigquery
    project_id: my-company-gcp-project
    credentials_file: my-workspace-bq.json
    datasets:
      - my-company-gcp-project.sales_warehouse
  marketing:
    name: Marketing Data
    type: bigquery
    project_id: my-company-gcp-project
    credentials_file: my-workspace-bq.json
    datasets:
      - my-company-gcp-project.marketing_events

Cada alias se vuelve referenciable de forma independiente en los models.

Working example: Postgres source

Los sources de Postgres separan coordenadas de red y credenciales: el dsn es una URI estándar de libpq (host, port, database, flags TLS o de pool) sin el user:password@; el user y password viven en un JSON dentro de secrets/ referenciado por credentials_file. La plataforma lee los dos, inyecta las credenciales en el DSN en memoria y lo pasa al driver de Postgres. runtime/sources.runtime.yml nunca contiene una password.

sources:
  warehouse:
    name: Internal Warehouse
    type: postgres
    dsn: "postgresql://pg.internal.example.com:5432/warehouse?sslmode=require"
    credentials_file: warehouse.json
    schemas:
      - reporting
      - public

Dropea el JSON correspondiente en secrets/warehouse.json:

{
  "user": "looky_reader",
  "password": "..."
}

Campo por campo:

  • type: tiene que ser postgres.
  • name: label humano opcional que se muestra en la UI cuando el source aparece en herramientas de operator. Puramente cosmético.
  • dsn: URI libpq sin userinfo. Tiene que empezar con postgres:// o postgresql://; el regex del schema rechaza cualquier URI que contenga @ (es decir, user:password@). Cualquier parámetro de query-string libpq — sslmode, application_name, connect_timeout, target_session_attrs, channel_binding, gssencmode, … — pasa intacto.
  • credentials_file: filename plano de un JSON adentro de la carpeta secrets/ del workspace. Pattern ^[A-Za-z0-9_-][A-Za-z0-9._-]*$ — sin separadores de path, sin punto inicial. El JSON tiene que declarar {"user": "…", "password": "…"}.
  • schemas: array opcional que limita la introspección. Default a todos los schemas no-sistema (pg_catalog e information_schema quedan siempre excluidos).

Working example: MySQL source

Los sources de MySQL siguen la misma separación que Postgres: el dsn es una URI mysql://host:port/database sin el user:password@, y el user y password viven en un JSON dentro de secrets/ referenciado por credentials_file. A diferencia de Postgres, un DSN de MySQL no lleva parámetros de query — Looky parsea el host, port y database de la URI y rechaza cualquier ?…. runtime/sources.runtime.yml nunca contiene una password.

sources:
  shop:
    name: Online Shop
    type: mysql
    dsn: "mysql://db.internal.example.com:3306/shop"
    credentials_file: shop.json
    schemas:
      - shop

Dropea el JSON correspondiente en secrets/shop.json:

{
  "user": "looky_reader",
  "password": "..."
}

Campo por campo:

  • type: tiene que ser mysql.
  • name: label humano opcional que se muestra en la UI cuando el source aparece en herramientas de operator. Puramente cosmético.
  • dsn: URI mysql://host:port/database sin userinfo. El regex del schema rechaza cualquier URI que contenga @ (es decir, user:password@) o un query string con ?. El port es opcional y default a 3306.
  • credentials_file: filename plano de un JSON adentro de la carpeta secrets/ del workspace. Pattern ^[A-Za-z0-9_-][A-Za-z0-9._-]*$ — sin separadores de path, sin punto inicial. El JSON tiene que declarar {"user": "…", "password": "…"}.
  • schemas: array opcional de databases a exponer para introspección. Default a la database nombrada en el dsn.

Dos cosas específicas de MySQL que conviene saber: las conexiones no van encriptadas (todavía no se puede configurar TLS hacia MySQL), así que usalo sobre una red de confianza; y MySQL no tiene un tipo boolean real, así que las columnas que parecen boolean vuelven como números — agrega un cast(… as boolean) explícito en tu model cuando necesites un filtro true/false.

Matriz de campos por adapter

Referencia rápida de qué requiere cada adapter:

  • BigQuery — requeridos: type: bigquery, project_id, credentials_file; opcionales: location, datasets (requeridos en tiempo de introspección, no en tiempo de validation). project_id es el billing project — otorga al service account BigQuery Job User sobre él. Lista bajo datasets: cada dataset que tus models consultan.
  • Postgres — requeridos: type: postgres, dsn (URI libpq sin userinfo), credentials_file (filename de un JSON en secrets/ con {"user","password"}); opcionales: schemas.
  • MySQL — requeridos: type: mysql, dsn (mysql://host:port/database, sin userinfo, sin query string), credentials_file (filename de un JSON en secrets/ con {"user","password"}); opcionales: schemas (default a la database del DSN).

credentials_file es siempre un filename plano dentro de secrets/ — sin slashes, sin path prefix. Los aliases de conexión de los models referencian exactamente los aliases que este archivo declara.

Para la matriz de divergencias completa por adapter (auth, binding de parámetros, manejo de NULL, dryRun, introspección, caching), mira la comparación de adapters de source.

Workflow de validación de sources

  1. Edita runtime/sources.runtime.yml desde el root de tu workspace.
  2. Corre:
    looky sources list
    looky sources diff
    looky validate
  3. Arregla errores de alias, credentials o dataset antes de tocar models — arreglalos acá, una vez, y mantén los models limpios.

sources list muestra los aliases de runtime actualmente registrados. sources diff muestra qué cambiaría en el push. validate chequea consistencia estructural sobre todo el workspace.