Reutilizar código com extends

Este é um tópico avançado que pressupõe que o leitor tem um conhecimento sólido do LookML.

Vista geral

À medida que o seu modelo LookML aumenta em tamanho e complexidade, torna-se cada vez mais útil reutilizar o LookML em vários locais. O parâmetro extends permite-lhe reutilizar código, o que ajuda a fazer o seguinte:

  • Escrever código DRY (não se repita), para que possa definir as coisas num único local, tornando o seu código mais consistente e mais rápido de editar
  • Faça a gestão de diferentes conjuntos de campos para diferentes utilizadores
  • Partilhe padrões de design em diferentes partes do seu projeto
  • Reutilize conjuntos de junções, dimensões ou medidas num projeto

Para estender um objeto LookML, cria um novo objeto LookML e, em seguida, adiciona o parâmetro extends para indicar que o novo objeto é uma extensão de um objeto existente. Isto significa que o seu projeto vai ter duas versões do objeto LookML. Se existirem conflitos, o objeto de extensão tem prioridade e substitui as definições do objeto que está a ser estendido. Consulte a secção Detalhes de implementação para extends mais adiante nesta página para ver detalhes.

Consulte os refinamentos do LookML: a extensão de uma vista ou de uma análise detalhada é ideal para cenários em que quer ter várias versões da vista ou da análise detalhada. No entanto, se o seu objetivo for simplesmente modificar uma vista ou uma análise detalhada sem editar o ficheiro LookML que a contém, é recomendável usar um refinamento. Também pode usar um parâmetro extends dentro de um refinamento. Consulte a página de documentação Refinamentos do LookML para ver mais informações e exemplos de utilização.

Pode expandir vistas, Explores e painéis de controlo do LookML:

Não é possível expandir os modelos, nem incluir um ficheiro de modelo noutro ficheiro de modelo. Em alternativa, se quiser reutilizar ou expandir as explorações em vários modelos, pode criar um ficheiro de exploração separado e, em seguida, incluir esse ficheiro de exploração num ficheiro de modelo.

Veja os seguintes exemplos de extensão de uma análise detalhada e extensão de um painel de controlo do LookML.

Estender uma opção a Explorar

Segue-se um exemplo de como estender uma análise detalhada:

explore: customer {
  persist_for: "12 hours"
}

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

Neste exemplo, temos uma análise detalhada denominada Cliente e criámos uma segunda análise detalhada denominada Transação que a expande. Tudo o que está em Customer, como as respetivas associações, é incluído em Transaction. Tudo o que estiver em Transação permanece em Transação.

No entanto, repare que existe um conflito: a análise detalhada Cliente indica que a definição persist_for deve ser de 12 horas, mas a análise detalhada Transação indica que deve ser de 5 minutos. Para a análise detalhada Transação, é usada a definição persist_for: "5 minutes", porque substitui a definição da análise detalhada que está a estender.

Estender um painel de controlo do LookML

Para estender um painel de controlo do LookML, os painéis de controlo estendido e de extensão têm de estar incluídos no ficheiro do modelo. Se um painel de controlo que usa o parâmetro extends estiver incluído num ficheiro de modelo sem o painel de controlo base que estende, recebe um erro de validação do LookML a indicar que não é possível encontrar o painel de controlo base (entre outros erros).

Segue-se um exemplo de um ficheiro de painel de controlo:

Ficheiro: 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 criar um novo ficheiro de painel de controlo LookML e expandir o painel de controlo FAA adicionando um novo mosaico:

Ficheiro: 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

Uma vez que expande o painel de controlo da FAA, o painel de controlo FAA Additional inclui todos os mosaicos definidos no ficheiro faa.dashboard.lookml. Além disso, o painel de controlo FAA Additional tem todos os mosaicos definidos no respetivo ficheiro faa_additional.dashboard.lookml.

A forma mais fácil de criar um painel de controlo do LookML é obter o LookML de um painel de controlo definido pelo utilizador. Também pode usar esta técnica para obter o LookML de mosaicos individuais do painel de controlo. Se estiver a usar este método, certifique-se de que as posições dos mosaicos não se sobrepõem. Nos exemplos faa.dashboard.lookml e faa_additional.dashboard.lookml, os mosaicos encontram-se na linha superior do painel de controlo, o que é indicado por row: 0:

Ficheiro: faa.dashboard.lookml


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

No entanto, o novo mosaico que estamos a adicionar no painel de controlo FAA Additional está em col: 8, pelo que é apresentado junto ao mosaico do painel de controlo expandido:

Ficheiro: faa_additional.dashboard.lookml


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

É fácil não reparar nisto, uma vez que estes elementos estão em ficheiros de painéis de controlo diferentes. Por isso, se estiver a adicionar mosaicos a um painel de controlo expandido, certifique-se de que verifica se existem conflitos de posicionamento entre os mosaicos no painel de controlo expandido e os mosaicos no painel de controlo de expansão.

Exigir extensão

Pode usar o parâmetro extension: required para sinalizar um objeto LookML como exigindo extensão, o que significa que o objeto não pode ser usado sozinho. Um objeto com extension: required não é visível para os utilizadores por si só. Destina-se apenas a servir de ponto de partida para ser expandido por outro objeto LookML. O parâmetro extension é suportado para explorações, vistas e painéis de controlo do LookML.

Não é possível usar um explore com extension: required como explore_source para um teste de dados. O validador do LookML gera um erro a indicar que não é possível encontrar o explore_source.

Usar metadados para ver extensões de um objeto

Pode clicar num parâmetro explore ou view no IDE do Looker e usar o painel de metadados para ver quaisquer extensões no objeto ou para ver a que objeto se estende. Consulte a página de documentação Metadados para objetos do LookML para ver informações.

Detalhes de implementação de extends

Estes são os passos que o Looker executa quando estende um objeto LookML:

  1. Copiar o objeto que está a ser estendido: o Looker faz uma cópia do LookML para a vista, a análise detalhada ou o painel de controlo do LookML que está a ser estendido. Esta nova cópia é o objeto de extensão.
  2. Unir o LookML das duas cópias: o Looker une o LookML do objeto estendido no objeto de extensão.
  3. Resolva conflitos entre as cópias: na maioria dos casos, se um elemento LookML for definido no objeto estendido e no objeto de extensão, é usada a versão no objeto de extensão. No entanto, noutros casos, as extensões combinam os valores dos parâmetros em vez de substituir os valores. Consulte a secção Combinar parâmetros nesta página para ver informações.
  4. Aplicar o LookML: depois de todos os conflitos serem resolvidos, o Looker interpreta o LookML resultante através da lógica padrão. Por outras palavras, o Looker usa todas as predefinições e pressupostos padrão, tal como acontece com qualquer outra vista, exploração ou painel de controlo do LookML.

As secções seguintes mostram os detalhes destes passos, usando a extensão de uma vista como exemplo. Segue-se o LookML para a nossa vista base, a vista User:

view: user {
  suggestions: yes

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

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

Segue-se o LookML para a vista User with Age Extensions, que expande a vista User:

include: "/views/user.view"

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

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

  dimension: status {
    type: string
  }
}

Passo 1: copie o LookML

Neste caso, a visualização user está a ser prolongada para a visualização user_with_age_extensions. Uma vez que user é a vista que está a ser expandida, é feita uma cópia da mesma antes da união. O facto de ser criada uma cópia não é particularmente importante aqui. No entanto, é importante saber que a vista user original permanece inalterada e pode ser usada normalmente.

Passo 2: junte as cópias

O passo seguinte é a união de todo o LookML da vista estendida (user) na vista de extensão (user_with_age_extensions). É importante compreender a natureza desta união, que é simplesmente uma união de objetos LookML. Na prática, isto significa que qualquer LookML escrito explicitamente é unido, mas os valores LookML predefinidos que não escreveu não são unidos. Em certo sentido, é apenas o texto do LookML que está a ser reunido, e não o significado desse texto.

Passo 3: resolva conflitos

O terceiro passo é resolver quaisquer conflitos entre as vistas unidas.

Na maioria dos casos, se um elemento LookML estiver definido no objeto estendido e no objeto de extensão, é usada a versão no objeto de extensão. No entanto, noutros casos, as extensões combinam os valores dos parâmetros em vez de substituir os valores. Consulte a secção Combinar parâmetros nesta página para ver informações.

No caso do exemplo user_with_age_extensions, nenhum dos parâmetros é aditivo e não são especificadas opções de lista nem palavras-chave sql especiais. Por isso, os valores dos parâmetros na vista de extensão substituem os valores dos parâmetros na vista expandida:

  • O nome da vista que está a ser estendida (user_with_age_extensions) substitui o nome da vista estendida (user).
  • O valor ing para suggestions: no substitui o valor ed suggestions: yes.
  • A vista de extensão tem uma dimensão denominada age, que não existe na vista estendida (sem conflito).
  • A vista estendida tem uma dimensão denominada name, que não existe na vista de extensão (sem conflito).
  • O valor type: string da dimensão status na vista em expansão substitui o valor type: number na vista expandida.
  • A dimensão status tem um parâmetro sql, que não existe na vista de extensão (sem conflito).

O facto de os valores LookML predefinidos ainda não estarem a ser considerados é importante, porque não quer cometer o erro de pensar que os conflitos entre os valores predefinidos estão a ser resolvidos. Na verdade, estão apenas a ser ignorados neste passo. É por isso que temos de adicionar explicitamente parâmetros adicionais quando estendemos objetos:

Neste exemplo específico, não adicionámos sql_table_name à vista Utilizador, o que vai causar alguns problemas no passo seguinte.

Passo 4: interprete o LookML normalmente

No passo final, o LookML resultante é interpretado normalmente, incluindo todos os valores predefinidos. Neste exemplo específico, o LookML resultante seria interpretado da seguinte forma:

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
  }
}

Repare que o LookML resultante inclui view: user_with_age_extensions, mas não o parâmetro sql_table_name. Como resultado, o Looker vai assumir que o valor de sql_table_name é igual ao nome da vista.

O problema é que provavelmente não existe nenhuma tabela na nossa base de dados com o nome user_with_age_extensions. É por isso que temos de adicionar um parâmetro sql_table_name a qualquer vista que vai ser expandida. Adicionar view_name e view_label a explorações que vão ser expandidas evita problemas semelhantes.

A combinação estende

Existem algumas formas de tirar partido dos objetos LookML com extends:

Para ver um exemplo de um exemplo de utilização avançado e ler sugestões de resolução de problemas, consulte a página de práticas recomendadas Resolução de problemas de um exemplo de utilização avançado de extends.

Estender mais do que um objeto em simultâneo

É possível expandir mais do que um painel de controlo, uma visualização ou uma exploração em simultâneo. Por exemplo:

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

O processo de extensão funciona exatamente como descrito no exemplo de implementação, mas existe uma regra adicional sobre a forma como os conflitos são resolvidos. Se existirem conflitos entre os vários itens indicados no parâmetro extends, é dada prioridade aos itens indicados por último. Assim, no exemplo anterior, se existissem conflitos entre user_info e marketing_info, a exploração marketing_info venceria.

Encadeamento de várias extensões

Também pode encadear o número de extensões que quiser. Por exemplo:

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

Mais uma vez, o processo de extensão funciona exatamente como descrito no exemplo de implementação, com uma regra adicional sobre a resolução de conflitos. Se existirem conflitos, é dada prioridade ao último item na cadeia de extensões. Neste exemplo:

  • orders teria prioridade sobre user_info e marketing_info.
  • user_info teria prioridade sobre marketing_info.

Combinar parâmetros

Na maioria dos casos, se um elemento LookML estiver definido no objeto estendido e no objeto de extensão, é usada a versão no objeto de extensão. Este foi o caso no exemplo de implementação nesta página.

No entanto, nos seguintes casos, as extensões combinam os valores dos parâmetros em vez de substituir os valores:

Alguns parâmetros são aditivos

Em muitos casos, se o objeto de extensão contiver o mesmo parâmetro que o objeto que está a ser estendido, os valores do objeto de extensão substituem os valores dos parâmetros do objeto estendido. No entanto, as extensões podem ser aditivas para alguns parâmetros, o que significa que os valores do objeto de extensão são usados em conjunto com os valores do objeto estendido.

Os seguintes parâmetros são aditivos:

No exemplo seguinte, a vista carriers tem uma dimensão name com um 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"
    }
  }
}

E aqui está a vista carriers_extended, que expande a vista carriers. A vista carriers_extended também tem uma dimensão name com definições diferentes no 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"
    }
  }
}

Na vista carriers_extended, os dois parâmetros link são aditivos, pelo que a dimensão name apresenta ambos os links.

Opções adicionais com listas

Quando trabalha com listas, pode optar por combiná-las, em vez de a lista do objeto de extensão ser a vencedora. Considere esta extensão simples com uma lista em conflito denominada animals:

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

Neste caso, a vista pets está a fazer a extensão e, por isso, vai ganhar, fazendo com que animals contenha [dog, cat]. No entanto, pode combinar as listas usando o conjunto especial EXTENDED*:

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

Agora, a lista animals vai conter [dog, cat, goldfish, guppy].

Combinar em vez de substituir durante a resolução de conflitos

Na maioria dos casos, se existirem conflitos durante a extensão, o objeto de extensão ganha. Por exemplo, considere esta extensão simples:

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

Pode ver que existe um conflito do parâmetro sql na dimensão description. Normalmente, a definição de product_short_descriptions substitui simplesmente a definição de products, porque está a fazer a extensão.

No entanto, também pode optar por combinar as definições, se quiser. Para o fazer, usa a palavra-chave ${EXTENDED} da seguinte forma:

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

Agora, o conflito do parâmetro sql vai ser resolvido de forma diferente. Em vez de a definição product_short_descriptions ser a vencedora, a definição é obtida a partir de products e inserida onde ${EXTENDED} é usado. A definição resultante para description neste caso é: LEFT(${TABLE}.full_description, 50).

Aspetos a considerar

Projetos com localização

Quando estende um objeto, tenha em atenção que as regras de localização também se aplicam às suas extensões. Se estiver a expandir um objeto e, em seguida, a definir novas etiquetas ou descrições, deve fornecer definições de localização nos ficheiros de strings de local do seu projeto. Consulte a página de documentação Localizar o seu modelo LookML para mais informações.