Reutilizar código con extends

Se trata de un tema avanzado que presupone que el lector tiene un conocimiento sólido de LookML.

Información general

A medida que tu modelo de LookML aumenta de tamaño y complejidad, resulta cada vez más útil reutilizar tu LookML en varios lugares. El parámetro extends te permite reutilizar código, lo que te ayuda a hacer lo siguiente:

  • Escribe código DRY (no te repitas) para poder definir elementos en un solo lugar, lo que hará que tu código sea más coherente y se pueda editar más rápido.
  • Gestionar diferentes conjuntos de campos para distintos usuarios
  • Compartir patrones de diseño en diferentes partes de un proyecto
  • Reutilizar conjuntos de combinaciones, dimensiones o medidas en un proyecto

Para ampliar un objeto LookML, crea un objeto LookML y añade el parámetro extends para indicar que el nuevo objeto es una extensión de un objeto ya creado. Esto significa que tu proyecto tendrá dos versiones del objeto LookML. Si hay algún conflicto, el objeto que se extiende tendrá prioridad y anulará la configuración del objeto que se está extendiendo. Para obtener más información, consulta la sección Detalles de la implementación de extends, que aparece más adelante en esta página.

Consulta los refinamientos de LookML: ampliar una vista o una Exploración es ideal en los casos en los que quieras tener varias versiones de la vista o de la Exploración. Sin embargo, si tu objetivo es simplemente modificar una vista o un Explorar sin editar el archivo LookML que lo contiene, te recomendamos que uses un refinamiento. También puedes usar un parámetro extends dentro de un refinamiento. Consulta la página de documentación Refinamientos de LookML para obtener más información y casos prácticos.

Puedes ampliar vistas, Exploraciones y paneles de control de LookML:

Los modelos no se pueden ampliar y no se puede incluir un archivo de modelo en otro. En su lugar, si quiere reutilizar o ampliar Exploraciones en varios modelos, puede crear un archivo de Exploración independiente y, a continuación, incluir ese archivo en un archivo de modelo.

Consulta los siguientes ejemplos de ampliación de un Exploración y de ampliación de un panel de LookML.

Ampliar un Explore

Aquí tienes un ejemplo de cómo ampliar una exploración:

explore: customer {
  persist_for: "12 hours"
}

explore: transaction {
  extends: [customer]
  persist_for: "5 minutes"
}

En este ejemplo, tenemos una Exploración llamada Cliente y hemos creado otra llamada Transacción que la amplía. Todo lo que haya en Customer, como sus combinaciones, se incluirá en Transaction. Todo lo que esté en Transacción permanecerá en Transacción.

Sin embargo, hay un conflicto: en la exploración Cliente, se indica que el ajuste persist_for debe ser de 12 horas, pero en la exploración Transacción, se indica que debe ser de 5 minutos. En el Explorar Transacción, se usará el ajuste persist_for: "5 minutes", ya que sobrescribe el ajuste del Explorar que amplía.

Ampliar un panel de control de LookML

Para ampliar un panel de control de LookML, tanto el panel de control ampliado como el que lo amplía deben incluirse en el archivo de modelo. Si se incluye un panel de control que usa el parámetro extends en un archivo de modelo sin el panel de control base al que extiende, se producirá un error de validación de LookML que indica que no se puede encontrar el panel de control base (entre otros errores).

Aquí tienes un ejemplo de archivo de panel de control:

Archivo: faa.dashboard.lookml

- dashboard: faa
  title: FAA Dashboard
  layout: newspaper
  elements:
  - title: Aircraft Location
    name: Aircraft Location
    model: e_faa
    explore: aircraft
    type: looker_map
    fields:
    - aircraft.zip
    - aircraft.count
    sorts:
    - aircraft.count desc
    limit: 500
    query_timezone: America/Los_Angeles
    series_types: {}
    row: 0
    col: 0
    width: 8
    height: 6

Podemos crear un archivo de panel de LookML y ampliar el panel FAA añadiendo una nueva baldosa:

Archivo: faa_additional.dashboard.lookml

- dashboard: faa_additional
  title: FAA Additional
  extends: faa
  elements:
  - title: Elevation Count
    name: Elevation Count
    model: e_faa
    explore: airports
    type: looker_scatter
    fields:
    - airports.elevation
    - airports.count
    sorts:
    - airports.count desc
    limit: 500
    query_timezone: America/Los_Angeles
    row: 0
    col: 8
    width: 8
    height: 6

Como amplía el panel de control FAA, el panel de control FAA Additional incluirá todas las tarjetas definidas en el archivo faa.dashboard.lookml. Además, el panel de control FAA Additional tendrá los recuadros definidos en su propio archivo faa_additional.dashboard.lookml.

La forma más sencilla de crear un panel de control de LookML es obtener el LookML de un panel de control definido por el usuario. También puedes usar esta técnica para obtener el LookML de los distintos baldosines de un panel de control. Si utilizas este método, asegúrate de que las posiciones de tus baldosas no se superpongan. En los ejemplos faa.dashboard.lookml y faa_additional.dashboard.lookml, las baldosas están en la fila superior del panel de control, que se indica con row: 0:

Archivo: faa.dashboard.lookml


    row: 0
    col: 0
    width: 8
    height: 6

Sin embargo, la nueva baldosa que vamos a añadir al panel de control Información adicional de la FAA está en col: 8, por lo que se muestra junto a la baldosa del panel de control ampliado:

Archivo: faa_additional.dashboard.lookml


    row: 0
    col: 8
    width: 8
    height: 6

Es fácil pasar por alto este detalle, ya que estos elementos se encuentran en archivos de panel de control diferentes. Por lo tanto, si añades baldosas a un panel de control ampliado, asegúrate de comprobar si hay conflictos de posición entre las baldosas del panel de control ampliado y las del panel de control que se está ampliando.

Requiere extensión

Puede usar el parámetro extension: required para marcar un objeto de LookML como obligatorio, lo que significa que el objeto no se puede usar por sí solo. Un objeto con extension: required no es visible para los usuarios por sí solo; solo se utiliza como punto de partida para que otro objeto LookML lo amplíe. El parámetro extension se admite en Exploraciones, vistas y paneles de LookML.

Un explore con extension: required no se puede usar como explore_source para una prueba de datos. El validador de LookML generará un error que indica que no se encuentra el explore_source.

Usar metadatos para ver las extensiones de un objeto

Puedes hacer clic en un parámetro explore o view en el IDE de Looker y usar el panel de metadatos para ver las extensiones del objeto o el objeto que extiende. Para obtener información, consulta la página de documentación Metadatos de objetos LookML.

Detalles de la implementación de extends

Estos son los pasos que sigue Looker al ampliar un objeto de LookML:

  1. Copiar el objeto que se está ampliando: Looker hace una copia del LookML de la vista, la Exploración o el panel de LookML que se está ampliando. Esta nueva copia es el objeto extend.
  2. Combinar el LookML de las dos copias: Looker combina el LookML del objeto extendido en el objeto extensor.
  3. Resuelve los conflictos entre las copias: por lo general, si un elemento de LookML se define tanto en el objeto extendido como en el objeto extensor, se utiliza la versión del objeto extensor. Sin embargo, en otros casos, las extensiones combinarán los valores de los parámetros en lugar de sustituirlos. Consulta la sección Combinar parámetros de esta página para obtener más información.
  4. Aplica el LookML: una vez que se hayan resuelto todos los conflictos, Looker interpreta el LookML resultante mediante la lógica estándar. Es decir, Looker usará todos los valores predeterminados y las suposiciones estándar, como con cualquier otra vista, exploración o panel de LookML.

En las siguientes secciones se muestran los detalles de estos pasos, y se amplía una vista como ejemplo. Este es el LookML de nuestra vista base, la vista User:

view: user {
  suggestions: yes

  dimension: name {
    sql: ${TABLE}.name ;;

  }
  dimension: status {
    sql: ${TABLE}.status ;;
    type: number
  }
}

Aquí tienes el LookML de la vista User with Age Extensions (Usuario con extensiones de edad), que extiende la vista User (Usuario):

include: "/views/user.view"

view: user_with_age_extensions {
  extends: [user]
  suggestions: no

  dimension: age {
    type: number
    sql: ${TABLE}.age ;;
  }

  dimension: status {
    type: string
  }
}

Paso 1: Copia el LookML

En este caso, la vista user se extiende a la vista user_with_age_extensions. Como user es la vista que se va a ampliar, se hace una copia de ella antes de combinarla. El hecho de que se haga una copia no es especialmente importante en este caso, pero sí lo es que la vista original user no se modifique y se pueda usar con normalidad.

Paso 2: Combina las copias

El siguiente paso es combinar todo el LookML de la vista extendida (user) en la vista extensora (user_with_age_extensions). Es importante entender la naturaleza de esta combinación, que es simplemente una combinación de objetos LookML. En la práctica, esto significa que se combinará cualquier código LookML escrito explícitamente, pero los valores predeterminados de LookML que no hayas escrito no se combinarán. En cierto modo, solo se está juntando el texto de LookML, no el significado de ese texto.

Paso 3: Resuelve los conflictos

El tercer paso es resolver los conflictos entre las vistas combinadas.

Por lo general, si un elemento de LookML se define tanto en el objeto extendido como en el objeto extensor, se usa la versión del objeto extensor. Sin embargo, en otros casos, las extensiones combinarán los valores de los parámetros en lugar de sustituirlos. Consulta la sección Combinar parámetros de esta página para obtener más información.

En el caso del ejemplo user_with_age_extensions, ninguno de los parámetros es aditivo y no se especifican opciones de lista ni palabras clave sql especiales, por lo que los valores de los parámetros de la vista ampliada sustituirán a los valores de los parámetros de la vista original:

  • El nombre de la vista extendida (user_with_age_extensions) anula el nombre de la vista extendida (user).
  • El valor de extensión de suggestions: no anula el valor de extendido suggestions: yes.
  • La vista extend tiene una dimensión llamada age, que no existe en la vista extended (no hay conflicto).
  • La vista extendida tiene una dimensión llamada name, que no existe en la vista extensión (no hay conflicto).
  • El valor type: string de la dimensión status en la vista extendida anula el valor type: number en la vista extendida.
  • La dimensión status tiene un parámetro sql, que no existe en la vista extendida (no hay conflicto).

Es importante tener en cuenta que los valores de LookML predeterminados aún no se tienen en cuenta, ya que no debes cometer el error de pensar que se están resolviendo los conflictos entre valores predeterminados. En realidad, solo se ignoran en este paso. Por eso, debemos añadir explícitamente parámetros adicionales al ampliar objetos:

En este ejemplo concreto, no hemos añadido sql_table_name a la vista Usuario, lo que va a provocar algunos problemas en el siguiente paso.

Paso 4: Interpreta el LookML como de costumbre

En el último paso, el LookML resultante se interpreta como normal, incluidos todos los valores predeterminados. En este ejemplo concreto, el LookML de la vista resultante se interpretaría de la siguiente manera:

include: "/views/user.view"

view: user_with_age_extensions {
  suggestions: no

  dimension: age {
    type: number
    sql: ${TABLE}.age ;;
  }

  dimension: name {
    sql: ${TABLE}.name ;;
  }

  dimension: status {
    sql: ${TABLE}.status ;;
    type: string
  }
}

Ten en cuenta que el LookML resultante incluye view: user_with_age_extensions, pero no el parámetro sql_table_name. Por lo tanto, Looker asumirá que el valor de sql_table_name es igual al nombre de la vista.

El problema es que probablemente no haya ninguna tabla en nuestra base de datos llamada user_with_age_extensions. Por eso, debemos añadir un parámetro sql_table_name a cualquier vista que se vaya a ampliar. Si añades view_name y view_label a Exploraciones que se van a ampliar, evitarás problemas similares.

Combinar extensiones

Hay varias formas de aprovechar los objetos de LookML con la función "extends":

Para ver un ejemplo de un caso práctico avanzado y leer consejos para solucionar problemas, consulta la página Prácticas recomendadas para solucionar problemas en un ejemplo de caso práctico avanzado de extends.

Extender más de un objeto al mismo tiempo

Puedes ampliar más de un panel de control, vista o Exploración al mismo tiempo. Por ejemplo:

explore: orders {
  extends: [user_info, marketing_info]
}
# Also works for dashboards and views

El proceso de extensión funciona exactamente como se describe en el ejemplo de implementación, pero hay una regla adicional sobre cómo se resuelven los conflictos. Si hay algún conflicto entre los distintos elementos que se indican en el parámetro extends, se dará prioridad a los elementos que se hayan indicado en último lugar. Por lo tanto, en el ejemplo anterior, si hubiera conflictos entre user_info y marketing_info, prevalecería la exploración marketing_info.

Encadenar varias extensiones

También puedes encadenar tantas extensiones como quieras. Por ejemplo:

explore: orders {
  extends: [user_info]
  ...
}
explore: user_info {
  extends: [marketing_info]
  ...
}

De nuevo, el proceso de extensión funciona exactamente como se describe en el ejemplo de implementación, con una regla adicional sobre la resolución de conflictos. Si hay algún conflicto, se da prioridad al último elemento de la cadena de extensiones. En este ejemplo:

  • orders tendría prioridad sobre user_info y marketing_info.
  • user_info tendría prioridad sobre marketing_info.

Combinar parámetros

Por lo general, si un elemento de LookML se define tanto en el objeto extendido como en el objeto extensor, se usa la versión del objeto extensor. Este es el caso del ejemplo de implementación de esta página.

Sin embargo, en los siguientes casos, las extensiones combinarán los valores de los parámetros en lugar de sustituirlos:

Algunos parámetros son acumulativos

En muchos casos, si el objeto de extensión contiene el mismo parámetro que el objeto que se está extendiendo, los valores del objeto de extensión prevalecerán sobre los valores de parámetro del objeto extendido. Sin embargo, las extensiones pueden ser aditivas para algunos parámetros, lo que significa que los valores del objeto de extensión se usan junto con los valores del objeto extendido.

Los siguientes parámetros son aditivos:

En el ejemplo siguiente, la vista carriers tiene una dimensión name con un parámetro link:

view: carriers {
  sql_table_name: flightstats.carriers ;;

  dimension: name {
    sql: ${TABLE}.name ;;
    type: string
    link: {
      label: "Google {{ value }}"
      url: "http://www.google.com/search?q={{ value }}"
      icon_url: "http://google.com/favicon.ico"
    }
  }
}

Aquí tienes la vista carriers_extended, que amplía la vista carriers. La vista carriers_extended también tiene una dimensión name con ajustes diferentes en el parámetro link:


include: "/views/carriers.view.lkml"

view: carriers_extended {
  extends: [carriers]

  dimension: name {
    sql: ${TABLE}.name ;;
    type: string
    link: {
      label: "Dashboard for {{ value }}"
      url: "https://docsexamples.dev.looker.com/dashboards/307?Carrier={{ value }}"
      icon_url: "https://www.looker.com/favicon.ico"
    }
  }
}

En la vista carriers_extended, los dos parámetros link son aditivos, por lo que la dimensión name mostrará ambos enlaces.

Opciones adicionales con listas

Cuando trabajes con listas, puedes combinarlas en lugar de que la lista del objeto de extensión sea la que prevalezca. Imagina que tienes esta extensión sencilla con una lista conflictiva llamada animals:

view: pets {
  extends: fish
  set: animals {
    fields: [dog, cat]
  }
}
view: fish {
  set: animals {
    fields: [goldfish, guppy]
  }
}

En este caso, la vista pets es la que se extiende y, por lo tanto, gana, lo que hace que animals contenga [dog, cat]. Sin embargo, si usas el conjunto especial EXTENDED*, puedes combinar las listas:

view: pets {
  extends: fish
  set: animals {
    fields: [dog, cat, EXTENDED*]
  }
}
view: fish {
  set: animals {
    fields: [goldfish, guppy]
  }
}

Ahora, la lista animals contendrá [dog, cat, goldfish, guppy].

Combinar en lugar de sustituir durante la resolución de conflictos

Por lo general, si hay algún conflicto durante la extensión, gana el objeto que se extiende. Por ejemplo, echa un vistazo a esta extensión sencilla:

view: product_short_descriptions {
  extends: products
  dimension: description {
    sql: ${TABLE}.short_description ;;
  }
}
view: products {
  dimension: description {
    sql: ${TABLE}.full_description ;;
  }
}

Como puede ver, hay un conflicto del parámetro sql en la dimensión description. Normalmente, la definición de product_short_descriptions simplemente sobrescribirá la de products porque es la que se está ampliando.

Sin embargo, también puedes combinar las definiciones si quieres. Para ello, utiliza la palabra clave ${EXTENDED} de la siguiente manera:

view: product_short_descriptions {
  extends: products
  dimension: description {
    sql: LEFT(${EXTENDED}, 50) ;;
  }
}
view: products {
  dimension: description {
    sql: ${TABLE}.full_description ;;
  }
}

Ahora, el conflicto del parámetro sql se abordará de forma diferente. En lugar de usar la definición de product_short_descriptions, se tomará la de products y se insertará donde se utilice ${EXTENDED}. En este caso, la definición resultante de description será LEFT(${TABLE}.full_description, 50).

Cuestiones que debes tener en cuenta

Proyectos con localización

Cuando amplíes un objeto, ten en cuenta que las reglas de localización también se aplican a tus extensiones. Si vas a ampliar un objeto y, a continuación, definir nuevas etiquetas o descripciones, debes proporcionar definiciones de localización en los archivos de cadenas de configuración regional de tu proyecto. Para obtener más información, consulta la página de documentación Localizar tu modelo de LookML.