Práticas recomendadas para repositórios

Este documento apresenta as seguintes informações sobre repositórios do Dataform:

Visão geral das práticas recomendadas de repositório no Dataform

Esta seção apresenta uma visão geral das práticas recomendadas para gerenciar o tamanho e a estrutura do repositório, além do ciclo de vida do código no Dataform.

Práticas recomendadas para o tamanho do repositório

O tamanho do repositório afeta vários aspectos do desenvolvimento no Dataform, como:

  • Colaboração
  • Legibilidade da base de código
  • Processos de desenvolvimento
  • Compilação do fluxo de trabalho
  • Execução do fluxo de trabalho

O Dataform aplica cotas e limites de API em recursos de compilação. Um repositório grande pode fazer com que ele exceda essas cotas e limites. Isso pode levar à falha na compilação e execução do seu fluxo de trabalho.

Para reduzir esse risco, recomendamos dividir repositórios grandes. Ao dividir um repositório grande, você divide um fluxo de trabalho grande em vários fluxos menores hospedados em repositórios diferentes e conectados por dependências entre repositórios.

Essa abordagem permite obedecer às cotas e aos limites do Dataform, implementar processos e permissões refinados e melhorar a legibilidade e a colaboração do codebase. No entanto, gerenciar repositórios divididos pode ser mais desafiador do que gerenciar um único repositório.

Para saber mais sobre o impacto do tamanho do repositório no Dataform, consulte Visão geral do tamanho do repositório. Para saber mais sobre as práticas recomendadas para dividir repositórios, consulte Dividir repositórios.

Práticas recomendadas para a estrutura do repositório

Recomendamos estruturar os arquivos no diretório definitions para refletir as etapas do seu fluxo de trabalho. Você pode adotar uma estrutura personalizada que melhor atenda às suas necessidades.

A estrutura recomendada de subdiretórios definitions reflete as etapas principais da maioria dos fluxos de trabalho:

  • sources para armazenar declarações de fontes de dados.
  • intermediate para armazenar a lógica de transformação de dados.
  • output para armazenar definições de tabelas de saída.
  • extras (opcional) para armazenar outros arquivos.

Os nomes de todos os arquivos no Dataform precisam estar em conformidade com as diretrizes de nomenclatura de tabela do BigQuery. Recomendamos que os nomes dos arquivos no diretório definitions de um repositório do Dataform reflitam a estrutura de subdiretório.

Para saber mais sobre as práticas recomendadas para estruturar e nomear arquivos em um repositório, consulte Estruturar código em um repositório.

Práticas recomendadas para o ciclo de vida do código

O ciclo de vida do código padrão no Dataform consiste nas seguintes fases:

Para gerenciar o ciclo de vida do código no Dataform, crie ambientes de execução, como desenvolvimento, preparação e produção.

Para saber mais sobre o ciclo de vida do código no Dataform, consulte Introdução ao ciclo de vida do código no Dataform.

Você pode manter os ambientes de execução em um único repositório ou em vários.

Ambientes de execução em um único repositório

É possível criar ambientes de execução isolados, como desenvolvimento, preparo e produção, em um único repositório do Dataform com substituições de compilação do espaço de trabalho e configurações de lançamento.

É possível criar ambientes de execução isolados das seguintes maneiras:

  • Divida as tabelas de desenvolvimento e produção por esquema.
  • Divida as tabelas de desenvolvimento e produção por esquema e projeto Google Cloud .
  • Divida as tabelas de desenvolvimento, preparo e produção por projeto Google Cloud .

Em seguida, é possível programar execuções em ambientes de teste e produção com configurações de fluxo de trabalho. Recomendamos acionar as execuções manualmente no ambiente de desenvolvimento.

Para saber mais sobre as práticas recomendadas para gerenciar o ciclo de vida do fluxo de trabalho no Dataform, consulte Práticas recomendadas para o ciclo de vida do fluxo de trabalho.

Ciclo de vida do código em vários repositórios

Para personalizar as permissões do Identity and Access Management em cada etapa do ciclo de vida do código, crie várias cópias de um repositório e armazene-as em diferentes projetos do Google Cloud .

Cada projeto Google Cloud serve como um ambiente de execução que corresponde a uma etapa do ciclo de vida do código, por exemplo, desenvolvimento e produção.

Nessa abordagem, recomendamos manter a base de código do repositório igual em todos os projetos. Para personalizar a compilação e a execução em cada cópia do repositório, use substituições de compilação do espaço de trabalho, configurações de lançamento e configurações de fluxo de trabalho.

Visão geral do tamanho do repositório

Esta seção ajuda você a entender como o tamanho do repositório afeta o desenvolvimento do fluxo de trabalho e o uso de recursos de compilação do Dataform, além de estimar o uso de recursos de compilação do seu repositório.

Sobre o tamanho do repositório no Dataform

O tamanho de um repositório afeta os seguintes aspectos do desenvolvimento no Dataform:

  • Colaboração. Vários colaboradores trabalhando em um repositório grande podem criar um número excessivo de solicitações de pull, aumentando o risco de conflitos de mesclagem.

  • Legibilidade da base de código. Um número maior de arquivos que compõem um fluxo de trabalho em um único repositório pode dificultar a navegação.

  • Processos de desenvolvimento. Algumas áreas de um grande fluxo de trabalho em um único repositório podem exigir permissões ou processos personalizados, como programação, que são diferentes das permissões e processos aplicados ao restante do fluxo de trabalho. Um repositório grande dificulta a adaptação dos processos de desenvolvimento a áreas específicas do fluxo de trabalho.

  • Compilação do fluxo de trabalho. O Dataform impõe limites de uso aos recursos de compilação. Um repositório grande pode exceder esses limites e causar falha na compilação.

  • Execução do fluxo de trabalho. Durante a execução, o Dataform executa o código do repositório no seu espaço de trabalho e implanta recursos no BigQuery. Quanto maior o repositório, mais tempo o Dataform leva para executá-lo.

Se o tamanho grande do repositório afetar negativamente seu desenvolvimento no Dataform, você poderá dividir o repositório em vários menores.

Sobre os limites de recursos de compilação do repositório

Durante o desenvolvimento, o Dataform compila todo o código do repositório no seu espaço de trabalho para gerar uma representação do fluxo de trabalho no repositório. Isso é chamado de resultado de compilação. O Dataform aplica limites de uso aos recursos de compilação.

Seu repositório pode exceder os limites de uso pelos seguintes motivos:

  • Um bug de loop infinito no código do repositório.
  • Um bug de vazamento de memória no código do repositório.
  • Um repositório grande, com mais de 1.000 ações de fluxo de trabalho.

Para mais informações sobre limites de uso em recursos de compilação, consulte Limites de recursos de compilação do Dataform.

Estimar o uso de recursos de compilação do seu repositório

Você pode estimar o uso dos seguintes recursos de compilação para seu repositório:

  • Uso do tempo da CPU.
  • Tamanho total máximo de dados serializados do gráfico gerado de ações definidas no seu repositório.

Para ter uma aproximação aproximada do uso atual do tempo de CPU de compilação para a compilação do seu repositório, cronometre a compilação do seu fluxo de trabalho do Dataform em uma máquina local Linux ou macOS.

  • Para cronometrar a compilação do fluxo de trabalho, execute o comando da CLI do Dataform dataform compile no seguinte formato dentro do repositório:

    time dataform compile
    

    O exemplo de código a seguir mostra um resultado da execução do comando time dataform compile:

    real    0m3.480s
    user    0m1.828s
    sys     0m0.260s
    

É possível tratar o resultado real como um indicador aproximado do uso de tempo da CPU para a compilação do repositório.

Para ter uma aproximação do tamanho total do gráfico gerado de ações no seu repositório, grave a saída do gráfico em um arquivo JSON. É possível tratar o tamanho do arquivo JSON descompactado como um indicador aproximado do tamanho total do gráfico.

  • Para gravar a saída do gráfico compilado do fluxo de trabalho em um arquivo JSON, execute o seguinte comando da CLI do Dataform no seu repositório:

    dataform compile --json > graph.json
    

Como dividir repositórios

Esta seção discute estratégias para dividir um repositório do Dataform e gerenciar dependências entre repositórios.

Os repositórios são as unidades principais do Dataform. Um repositório armazena todos os arquivos SQLX e JavaScript que compõem seu fluxo de trabalho, além dos pacotes e arquivos de configuração do Dataform. É possível armazenar um fluxo de trabalho em um único repositório ou dividir um fluxo de trabalho entre vários repositórios.

Dividir um repositório no Dataform tem as seguintes vantagens:

  • Respeitar os limites do Dataform no uso de recursos de compilação. Dividir um fluxo de trabalho grande em vários repositórios menores reduz o risco de exceder os limites do Dataform nos recursos de compilação.
  • Processos de refinamento. É possível definir processos, como regras de integração contínua (CI), individualmente para cada fragmento dividido do fluxo de trabalho e para a equipe que o desenvolve.
  • Permissões detalhadas. É possível definir permissões individualmente para cada fragmento dividido do fluxo de trabalho e para a equipe que o desenvolve, a fim de aumentar a segurança geral do fluxo.
  • Melhorar a colaboração minimizando o número de colaboradores que trabalham em cada fragmento dividido do fluxo de trabalho.
  • Melhorar a legibilidade da base de código. Dividir os arquivos que compõem um fluxo de trabalho grande em vários repositórios facilita a navegação em cada um deles individualmente do que em todo o fluxo de trabalho de uma vez.
  • Acelerar a execução do fluxo de trabalho de cada fragmento dividido em comparação com a execução do fluxo de trabalho inteiro.

Dividir um repositório no Dataform tem as seguintes desvantagens:

  • Configuração personalizada de integração e desenvolvimento contínuos (CI/CD) necessária para cada repositório do Dataform e o repositório do Git correspondente.
  • Configuração de programação personalizada necessária para cada repositório do Dataform e o repositório Git correspondente.
  • Dificuldade em gerenciar dependências entre os objetos do fluxo de trabalho hospedados em vários repositórios.
  • Falta de uma visualização abrangente do gráfico acíclico dirigido (DAG) do fluxo de trabalho SQL dividido entre vários repositórios. Em cada repositório, o DAG gerado representa apenas uma parte do fluxo de trabalho completo.

Estratégias para dividir um repositório

Ao dividir um repositório, você divide os arquivos que compõem um fluxo de trabalho SQL principal em fluxos de trabalho filhos menores hospedados em repositórios separados do Dataform.

Você pode dividir um repositório de uma das seguintes maneiras:

  • Um repositório por equipe de desenvolvimento.
  • Um repositório por domínio, por exemplo, vendas, marketing ou logística.
  • Um repositório central e um repositório por domínio que usa o conteúdo do repositório central como fontes de dados.

Para hospedar o fluxo de trabalho principal em uma plataforma de hospedagem Git de terceiros, você precisa conectar individualmente cada um dos repositórios separados que contêm fluxos de trabalho filhos a um repositório Git dedicado de terceiros.

Gerenciar dependências entre repositórios

A maneira mais eficiente de dividir um repositório é dividir o fluxo de trabalho SQL principal em fluxos de trabalho filhos independentes, criando repositórios independentes. Um repositório independente não usa o conteúdo de outro repositório como fonte de dados. Essa abordagem não exige o gerenciamento de dependências entre repositórios.

Quando não é possível evitar dependências entre repositórios, elas podem ser gerenciadas dividindo um repositório em uma sucessão de repositórios, em que um repositório depende do antecessor e é uma fonte de dados para o sucessor. A sucessão de repositórios e dependências precisa refletir melhor a estrutura do fluxo de trabalho principal.

É possível criar dependências entre repositórios com declarações de fonte de dados do Dataform. É possível declarar um tipo de tabela do BigQuery de um repositório diferente do Dataform como uma fonte de dados no repositório que está sendo editado. Depois de declarar uma fonte de dados, é possível fazer referência a ela como qualquer outra ação de fluxo de trabalho do Dataform e usá-la para desenvolver seu fluxo de trabalho.

Ao programar a execução de um fluxo de trabalho dividido entre repositórios com dependências entre eles, é necessário executar os repositórios um por um na ordem das dependências.

Recomendamos evitar dividir um repositório em um grupo com dependências bidirecionais. Uma dependência bidirecional entre repositórios ocorre quando um repositório é uma fonte de dados para outro e também usa esse repositório como uma fonte de dados. Dependências bidirecionais entre repositórios complicam o agendamento e a execução do fluxo de trabalho principal, além dos processos de desenvolvimento.

Como estruturar o código em um repositório

Nesta seção, descrevemos as práticas recomendadas para estruturar e nomear arquivos de fluxo de trabalho no diretório raiz definitions de um repositório do Dataform. A estrutura recomendada do diretório definitions reflete as etapas de um fluxo de trabalho. Você pode adotar qualquer estrutura que atenda às necessidades da sua empresa.

Estruture o código do fluxo de trabalho no diretório definitions pelos seguintes motivos:

  • Melhorar a colaboração na base de código ao designar equipes para partes selecionadas do fluxo de trabalho.
  • Melhorar a capacidade de manutenção do fluxo de trabalho em caso de mudanças organizacionais.
  • Melhorar a navegação pelo seu codebase.
  • Melhorar a escalonabilidade da base de código.
  • Minimizar a sobrecarga administrativa da sua equipe.

O diretório raiz definitions em um repositório do Dataform contém código que cria elementos do seu fluxo de trabalho. É possível organizar arquivos no diretório definitions em uma estrutura de diretórios que reflita a estrutura do fluxo de trabalho.

Ao desenvolver um fluxo de trabalho, você declara tabelas de origem e as transforma para criar tabelas de saída que podem ser usadas para fins comerciais ou de análise.

É possível distinguir três estágios principais de um fluxo de trabalho:

  1. Declaração de fontes de dados.
  2. Transformação dos dados de origem.
  3. Definição das tabelas de saída com base nos dados de origem transformados.

A estrutura a seguir de subdiretórios no diretório definitions reflete os principais estágios de um fluxo de trabalho:

sources
Declarações de fontes de dados e transformação básica de dados de origem, por exemplo, filtragem.
intermediate
Tabelas e ações que leem de sources e transformam dados antes de usar os dados transformados para definir tabelas outputs. As tabelas normalmente não são expostas a outros processos ou ferramentas, como as de business intelligence (BI), depois que o Dataform as executa no BigQuery.
outputs
Definições de tabelas consumidas por processos ou ferramentas, como BI, depois que o Dataform as executa no BigQuery.
extra
Arquivos fora do pipeline principal do fluxo de trabalho, por exemplo, arquivos que contêm dados de fluxo de trabalho preparados para uso adicional, como machine learning. Um subdiretório opcional e personalizado.

Práticas recomendadas para sources

O subdiretório sources contém a primeira etapa do fluxo de trabalho: a declaração e a transformação básica dos dados de origem.

No subdiretório sources, armazene declarações de fontes de dados e tabelas que filtram, categorizam, convertem ou renomeiam colunas.

Evite armazenar tabelas que combinam dados de várias fontes.

Transforme dados de sources em tabelas armazenadas no subdiretório intermediate.

Se você declarar fontes de dados de vários pools, por exemplo, Google Ads ou Google Analytics, dedique um subdiretório a cada pool.

O exemplo a seguir mostra uma estrutura de subdiretório de sources com dois pools de origem:

definitions/
    sources/
        google_ads/
            google_ads_filtered.sqlx
            google_ads_criteria_metrics.sqlx
            google_ads_criteria_metrics_filtered.sqlx
            google_ads_labels.sqlx
            google_ads_labels_filtered.sqlx
        google_analytics/
            google_analytics_users.sqlx
            google_analytics_users_filtered.sqlx
            google_analytics_sessions.sqlx

Se você declarar várias tabelas de origem de dados no mesmo esquema, poderá consolidar as declarações em um único arquivo JavaScript.

Para mais informações sobre como criar declarações de fonte de dados com JavaScript, consulte Criar fluxos de trabalho exclusivamente com JavaScript.

O exemplo de código a seguir mostra várias fontes de dados em um esquema, declaradas em um único arquivo JavaScript:

[
  "source_table_1",
  "source_table_2",
  "source_table_3"
].forEach((name) =>
  declare({
    database: "gcp_project",
    schema: "source_dataset",
    name,
  })
);

Para proteger seu fluxo de trabalho contra mudanças na fonte de dados, crie uma visualização para cada declaração de fonte de dados, por exemplo, analytics_users_filtered.sqlx. Ela pode conter a filtragem e a formatação básicas dos dados de origem. Armazene as visualizações no subdiretório sources.

Em seguida, ao criar tabelas intermediate ou outputs, faça referência às visualizações em vez das tabelas de origem brutas. Essa abordagem permite testar as tabelas de origem. Se uma tabela de origem mudar, você poderá modificar a visualização dela, por exemplo, adicionando filtros ou convertendo dados.

Práticas recomendadas para intermediate

O subdiretório intermediate contém a segunda etapa do fluxo de trabalho: a transformação e a agregação dos dados de origem de uma ou várias fontes.

No subdiretório intermediate, armazene arquivos que transformam significativamente os dados de origem de uma ou várias fontes no subdiretório sources, por exemplo, tabelas que combinam dados. As tabelas no subdiretório intermediate geralmente consultam dados de tabelas de origem ou outras tabelas intermediate.

Use tabelas intermediate para criar tabelas outputs. Normalmente, as tabelas intermediate não são usadas para outras finalidades, como análise de dados, depois que o Dataform as executa no BigQuery. Pense nas tabelas intermediate como a lógica de transformação de dados que permite a criação de tabelas de saída.

Recomendamos que você documente e teste todas as tabelas intermediate.

Práticas recomendadas para outputs

O subdiretório outputs contém a etapa final do fluxo de trabalho: a criação de tabelas de saída para fins comerciais com base nos dados transformados.

No diretório outputs, armazene tabelas que você planeja usar em outros processos ou ferramentas depois que o Dataform as executar no BigQuery, por exemplo, relatórios ou painéis. As tabelas no diretório outputs geralmente consultam dados das tabelas intermediate.

Agrupe as tabelas outputs pela entidade comercial a que estão relacionadas, por exemplo, marketing, pedidos ou análises. Dedique um subdiretório a cada entidade comercial.

Para armazenar tabelas de saída separadamente no BigQuery, configure um esquema dedicado para elas. Para instruções sobre como configurar o esquema da tabela, consulte Substituir configurações da tabela.

O exemplo a seguir mostra uma estrutura de subdiretório de outputs com entidades comerciais sales e marketing:

definitions/
    outputs/
        orders/
            orders.sqlx
            returns.sqlx
        sales/
            sales.sqlx
            revenue.sqlx
        marketing/
            campaigns.sqlx

Recomendamos que você documente e teste todas as tabelas outputs.

Estratégia de nomenclatura

Os nomes de todos os arquivos no Dataform precisam estar de acordo com as diretrizes de nomenclatura de tabelas do BigQuery.

Recomendamos que os nomes dos arquivos no diretório definitions de um repositório do Dataform reflitam a estrutura de subdiretórios.

No subdiretório sources, os nomes dos arquivos precisam apontar para a fonte a que o arquivo está relacionado. Adicione o nome da fonte como um prefixo aos nomes de arquivo. Por exemplo, analytics_filtered.sqlx

No subdiretório intermediate, os nomes dos arquivos precisam identificar o subdiretório para que os colaboradores possam distinguir claramente os arquivos intermediate. Selecione um prefixo exclusivo e aplique-o somente aos arquivos no diretório intermediate, por exemplo, stg_ads_concept.sqlx.

No subdiretório outputs, os nomes de arquivos precisam ser concisos, por exemplo, orders.sqlx. Se você tiver outputs tabelas com os mesmos nomes em subdiretórios de entidades diferentes, adicione um prefixo que identifique a entidade — por exemplo, sales_revenue.sqlx ou ads_revenue.sqlx.

O exemplo a seguir mostra uma estrutura de subdiretório dentro do diretório definitions com nomes de arquivos que seguem a estratégia de nomenclatura recomendada:

definitions/
    sources/
        google_analytics.sqlx
        google_analytics_filtered.sqlx
    intermediate/
        stg_analytics_concept.sqlx
    outputs/
        customers.sqlx
        sales/
            sales.sqlx
            sales_revenue.sqlx
        ads/
            campaigns.sqlx
            ads_revenue.sqlx

A seguir