Docs / Reference

Diferencias entre adapters de source

Por qué existe esta página

Looky soporta tres adapters de source: BigQuery, Postgres y MySQL. La mayor parte de la plataforma se comporta idéntica en los tres. Un puñado de áreas se comportan distinto — esas son las que tropiezan a autores de model y dashboard. Esta página lista cada una en términos observables (lo que ves, no cómo está implementado).

Declaración de source

BigQuery

  • Requeridos: type: bigquery, project_id (el proyecto de GCP que paga las queries), credentials_file (filename plano del JSON de service account dentro de secrets/ — sin path).
  • Opcionales: location para datasets multi-region, datasets (requeridos en tiempo de introspección de schema).

Postgres

  • Requeridos: type: postgres, dsn (URI libpq sin user:password@; lleva host, port, database, y cualquier flag de query-string libpq como sslmode=require, application_name, connect_timeout, …), credentials_file (filename de un JSON en secrets/ con {"user", "password"}).
  • Opcionales: name (label cosmético), schemas (limita el scope de introspección; default es todos los schemas no-sistema).

MySQL

  • Requeridos: type: mysql, dsn (URI mysql://host:port/database sin user:password@ y sin parámetros ?query — el port default a 3306), credentials_file (filename de un JSON en secrets/ con {"user", "password"}).
  • Opcionales: name (label cosmético), schemas (databases a introspeccionar; default es la database nombrada en el dsn).
  • Nota: las conexiones MySQL no van encriptadas — todavía no hay opción TLS, así que usá MySQL sobre una red de confianza.

Mirá Sources para ejemplos funcionando por adapter.

Introspección de schema

  • BigQuery — requiere una lista explícita de datasets. Sin eso, la introspección no puede encontrar tablas.
  • Postgres — descubre tablas entre los schemas en tu lista schemas (o el smart default de cada schema no-sistema). No hace falta declaración de table-list.
  • MySQL — descubre tablas en la database nombrada en el dsn (o las databases en tu lista schemas). Las databases de sistema (mysql, performance_schema, sys, information_schema) quedan siempre excluidas. No hace falta declaración de table-list.

Los mensajes de error en fallas de introspección se ven completamente distintos por adapter — cuando estés en duda, corré primero una pequeña query de test para confirmar que Looky puede llegar al source.

Parameter binding

Parámetros string, numéricos y array

Se comportan idéntico en los tres adapters. No hace falta manejo especial.

Parámetros date y timestamp

  • BigQuery — bindean nativos, sin trabajo extra.
  • Postgres y MySQL — el binding nativo falla con un error explícito en algunos shapes de query. Agregá un placeholder @param en el SQL subyacente de ese source así Looky sustituye el valor dentro del string SQL. Mirá Soporte de Malloy para un ejemplo trabajado.

Tipos de filtro que producen parámetros date / timestamp: cutoff_date, date_range, date_range_preset. Planeá para el patrón @param cuando esos filtros manejen un model con backing en Postgres o MySQL.

Valores NULL de parámetro

Cada adapter escribe un null tipado distinto: BigQuery y MySQL requieren un cast explícito, Postgres usa un null tipado pelado. Looky maneja esto por vos — no hay nada que configurar — pero es la razón por la que un parámetro nullable malformado puede fallar en un adapter y silenciosamente funcionar en otro.

Valores boolean (solo MySQL)

MySQL no tiene un tipo boolean real — las columnas que parecen boolean vuelven como números (0/1). Para filtrar sobre una condición true/false, agregá un cast(… as boolean) explícito en el model. BigQuery y Postgres tienen booleans nativos y no necesitan ese cast.

Ejecución de queries

  • BigQuery — expone una estimación de costo pre-flight gratis (en bytes escaneados) antes del run real. Útil para planear contra queries scan-heavy.
  • Postgres y MySQL — pre-flight valida el SQL plan (vía EXPLAIN) pero no estima costo.

Filtros y cross-filtering

El resolver de filtros y el mecanismo de pill de cross-filter son agnósticos del adapter. Las diferencias solo aparecen en el paso de parameter-binding descrito arriba.

  • Un filtro select se comporta idéntico en los tres.
  • Los filtros de fecha aterrizan en la caveat de parámetro temporal para Postgres y MySQL — arreglá del lado del model con @param.
  • Los valores de pill de Cross-filtering son típicamente strings o identifiers cortos, así que no se afectan.

Paginación (grid & report_matrix)

La paginación server-side usa el mismo protocolo en los tres adapters. Las características de costo difieren:

  • BigQuery — cada página sin cache es un scan facturado. Page size más grande + caching es más barato en total. Evitá grids sin bound en queries sin cache.
  • Postgres y MySQL — la latencia roundtrip de conexión domina; el costo depende mayormente del performance del indexed-scan de las tablas subyacentes. Asegurate que las columnas referenciadas en order by tengan índices apropiados.

Recomendaciones de cache TTL

La lógica del cache en sí es la misma en los tres adapters. La elección de TTL es editorial:

  • BigQuery — favorecé TTLs más largos para queries que escanean tablas grandes. Un TTL de 30 minutos en un dataset de batch diario es overkill; un TTL de 24 horas usualmente está bien.
  • Postgres y MySQL — el TTL es mayormente sobre freshness en vez de costo. El caching ayuda menos si la tabla subyacente es chica y bien indexada; considerá si el costo ahorrado supera el staleness introducido.

Agregaciones y features de dialecto

Looky no se ramifica en adapter para funciones agregadas o windowing. Cualquier cosa específica de dialecto (funciones ARRAY solo de BigQuery, date_trunc de Postgres en ciertos tipos, funciones de fecha solo de MySQL, etc.) aparece como un error de compilación de Malloy. El fix es del lado de Malloy — ajustá el model para usar un feature que todos los adapters de destino soportan, o protegé el model contra el adapter equivocado.

Patrones de migración trabajados

Un filtro de fecha que funciona en BigQuery pero rompe en Postgres o MySQL

El model con binding nativo:

# funciona en BigQuery, frágil en Postgres / MySQL en algunos shapes
##! experimental.parameters

source: orders(
  p_date_from::date is @2024-01-01,
  p_date_to::date   is @2024-12-31
) is bigquery.table('...') extend {

  view: revenue is {
    where:
      created_at::date >= p_date_from
      and created_at::date <= p_date_to
    aggregate:
      revenue is sum(sale_price)
  }
}

Cambiá el source a sql() con placeholders para compatibilidad con Postgres / MySQL (este ejemplo usa sintaxis Postgres; en MySQL usá el equivalente mysql.sql("""…""") con casts del dialecto MySQL):

# funciona en Postgres (y BigQuery)
##! experimental.parameters

source: orders(
  p_date_from::date is null,
  p_date_to::date   is null
) is postgres.sql("""
  select *
  from orders
  where (@date_from::date is null or created_at::date >= @date_from::date)
    and (@date_to::date   is null or created_at::date <= @date_to::date)
""") extend {
  view: revenue is {
    aggregate:
      revenue is sum(sale_price)
  }
}

Cada placeholder @param tiene que tener una declaración matcheante en la signature del source; Looky sustituye el valor (o NULL tipado cuando está unset) antes del compile.

Un grid que pagina bien en Postgres / MySQL pero hace explotar el scan budget de BigQuery

Subí pagination.page_size, agregá un cache sidecar con TTL largo, y pre-agregá cuando sea posible. En BigQuery, paginar a través de millones de filas sin cache es caro — pre-resumí.

Quick reference

  • Auth de source — BigQuery: archivo de service account. Postgres / MySQL: connection string + un secret {"user","password"}.
  • Transporte — BigQuery / Postgres: TLS disponible. MySQL: todavía sin encriptar.
  • Introspección — BigQuery: datasets explícitos requeridos. Postgres: schemas smart-default. MySQL: la database del DSN (o una lista schemas).
  • Parámetros numéricos / string — idéntico.
  • Parámetros date / timestamp — BigQuery: nativo. Postgres / MySQL: necesitan placeholder @param en SQL.
  • Booleans — nativos en BigQuery / Postgres. MySQL: numéricos — casteá explícitamente.
  • Parámetros NULL — manejados automáticamente; sin configuración.
  • Pre-flight — BigQuery: estimación de costo gratis. Postgres / MySQL: chequeo de SQL plan.
  • Filtros & routing de cross-filter — idéntico.
  • Protocolo de paginación — idéntico; las características de costo difieren.
  • Agregaciones / features de dialecto — delegado enteramente a Malloy; sin ramificaciones del lado de Looky.