Como carregar dados Parquet do Cloud Storage

Nesta página, apresentamos uma visão geral de como carregar dados Parquet do Cloud Storage no BigQuery.

O formato de dados Parquet (em inglês) é orientado por colunas, tem código aberto e é muito usado no ecossistema do Apache Hadoop.

É possível que os dados Parquet sejam carregados pelo Cloud Storage em uma nova tabela ou partição. Outra opção é anexá-los a uma tabela ou partição atual, bem como substituí-las. Quando os dados são carregados no BigQuery, eles são convertidos no formato de colunas Capacitor, formato de armazenamento do BigQuery.

Quando você carrega dados do Cloud Storage em uma tabela do BigQuery, o conjunto de dados que contém a tabela precisa estar na mesma região ou multirregião que o bucket do Cloud Storage.

Para informações sobre como carregar dados Parquet de um arquivo local, consulte Como carregar dados no BigQuery de uma fonte de dados local.

Esquemas Parquet

Quando você carrega arquivos Parquet no BigQuery, o esquema da tabela é recuperado automaticamente pelos dados de origem autodescritivos. Quando o BigQuery recupera o esquema dos dados de origem, o último arquivo em ordem alfabética é usado.

Por exemplo, você tem os seguintes arquivos Parquet no Cloud Storage:

    gs://mybucket/00/
      a.parquet
      z.parquet
    gs://mybucket/01/
      b.parquet
    

Esse comando carrega todos os arquivos em um comando CLI único (como uma lista separada por vírgulas) e o esquema é derivado de mybucket/01/b.parquet:

    bq load \
    --source_format=PARQUET \
    dataset.table \
    "gs://mybucket/00/*.parquet","gs://mybucket/01/*.parquet"
    

Quando você carrega vários arquivos Parquet com esquemas diferentes, as colunas idênticas especificadas em vários esquemas precisam ter o mesmo modo em cada definição de esquema.

Quando o BigQuery detecta o esquema, alguns tipos de dados Parquet são convertidos em tipos de dados do BigQuery para torná-los compatíveis com a sintaxe SQL do BigQuery. Para mais informações, consulte Conversões Parquet.

Compactação Parquet

O BigQuery é compatível com os seguintes codecs de compactação para blocos de dados em arquivos Parquet:

  • Snappy
  • GZip
  • LZO_1X

Permissões necessárias

Ao carregar dados no BigQuery, você precisa de permissões para executar um job de carregamento e para carregar dados em tabelas e partições novas ou antigas do BigQuery. Se você estiver carregando dados do Cloud Storage, também precisará de permissões para acessar o bucket que contém os dados.

Permissões do BigQuery

Pelo menos as permissões a seguir são obrigatórias para carregar dados no BigQuery. Elas serão necessárias se você estiver carregando dados em uma nova tabela ou partição ou anexando/substituindo uma tabela ou partição.

  • bigquery.tables.create
  • bigquery.tables.updateData
  • bigquery.jobs.create

Os seguintes papéis predefinidos do Cloud IAM incluem as permissões bigquery.tables.create e bigquery.tables.updateData:

  • bigquery.dataEditor
  • bigquery.dataOwner
  • bigquery.admin

Os seguintes papéis predefinidos do Cloud IAM incluem permissões bigquery.jobs.create:

  • bigquery.user
  • bigquery.jobUser
  • bigquery.admin

Além disso, se um usuário tiver permissões bigquery.datasets.create ao criar um conjunto de dados, ele receberá o acesso bigquery.dataOwner. Ao receber o acesso bigquery.dataOwner, o usuário consegue criar e atualizar tabelas no conjunto de dados por meio de um job de carregamento.

Consulte Controle de acesso para mais informações sobre papéis e permissões do Cloud IAM no BigQuery.

Permissões do Cloud Storage

Para carregar dados de um bucket do Cloud Storage, você precisa ter as permissões storage.objects.get. Se você estiver usando um caractere curinga de URI, também precisará ter permissões storage.objects.list.

O papel predefinido storage.objectViewer do Cloud IAM concede as permissões storage.objects.get e storage.objects.list.

Como carregar dados Parquet em uma nova tabela

É possível carregar dados Parquet em uma nova tabela:

  • usando o Console do Cloud ou a IU clássica da Web;
  • usando o comando bq load da CLI;
  • chamando o método da API jobs.insert e configurando um job load;
  • usando as bibliotecas de cliente.

Para carregar dados Parquet do Cloud Storage em uma nova tabela do BigQuery:

Console

  1. Abra a IU da Web do BigQuery no Console do Cloud.
    Acessar o Console do Cloud

  2. Na seção Recursos do painel de navegação, abra o projeto e selecione um conjunto de dados.

  3. No lado direito da janela, no painel de detalhes, clique em Criar tabela. O processo de carregamento de dados é igual ao de criação de uma tabela vazia.

    Criar tabela

  4. Na seção Origem da página Criar tabela, faça o seguinte:

    • Em Criar tabela de, selecione "Cloud Storage".

    • No campo de origem, procure ou insira o URI do Cloud Storage. Não é possível incluir vários URIs no Console do Cloud, mas os caracteres curingas são compatíveis. O bucket do Cloud Storage precisa estar no mesmo local que o conjunto de dados que contém a tabela a ser criada.

      Selecionar arquivo

    • Em Formato do arquivo, selecione Parquet.

  5. Na página Criar tabela, na seção Destino, faça o seguinte:

    • Em Nome do conjunto de dados, escolha o conjunto de dados apropriado.

      Ver conjunto de dados

    • Verifique se o Tipo de tabela está definido como Tabela nativa.

    • No campo Nome da tabela, insira o nome da tabela que você está criando no BigQuery.

  6. Na seção Esquema, nenhuma ação é necessária. O esquema é descrito automaticamente nos arquivos Parquet.

  7. (Opcional) Para particionar a tabela, escolha as opções em Configurações de particionamento e cluster:

    • Para criar uma tabela particionada, clique em Sem particionamento, selecione Partição por campo e escolha uma coluna DATE ou TIMESTAMP. Essa opção ficará indisponível se o esquema não incluir uma coluna DATE ou TIMESTAMP.
    • Para criar uma tabela particionada por tempo de ingestão, clique em Sem particionamento e selecione Partição por tempo de ingestão.
  8. (Opcional) Em Filtro de particionamento, clique na caixa Exigir filtro de particionamento para solicitar que os usuários incluam uma cláusula WHERE que especifique as partições a serem consultadas. A exigência de um filtro de particionamento pode reduzir os custos e melhorar o desempenho. Para mais informações, veja Como consultar tabelas particionadas. Essa opção ficará indisponível se a opção Sem particionamento estiver selecionada.

  9. (Opcional) Para inserir a tabela em um cluster, insira até quatro nomes de campo na caixa Ordem de clustering. Atualmente, o agrupamento em cluster é compatível apenas com tabelas particionadas.

  10. (Opcional) Clique em Opções avançadas.

    • Em Preferência de gravação, selecione Gravar apenas se a tabela estiver vazia. Essa opção cria uma nova tabela e carrega seus dados nela.
    • Em Número de erros permitidos, aceite o valor padrão 0 ou insira o número máximo de linhas contendo erros que podem ser ignorados. Se o número de linhas com erros exceder esse valor, o job exibirá uma mensagem invalid e falhará.
    • Em Valores desconhecidos, deixe a opção Ignorar valores desconhecidos desmarcada. Essa opção se refere apenas a arquivos CSV e JSON.
    • Em Criptografia, clique em Chave gerenciada pelo cliente para usar uma chave do Cloud Key Management Service. Se você optar pela configuração Chave gerenciada pelo Google, o BigQuery criptografará os dados em repouso.
  11. Clique em Criar tabela.

IU clássica

  1. Acesse a IU da Web do BigQuery.
    Acessar a IU da Web do BigQuery

  2. No painel de navegação, passe o cursor do mouse sobre um conjunto de dados, clique no ícone de seta para baixo imagem do ícone de seta para baixo e selecione Create new table. O processo de carregamento de dados é igual ao de criação de uma tabela vazia.

  3. Na página Create table, na seção Source Data:

    • Clique em Create from source.
    • Em Location, selecione Cloud Storage e, no campo de origem, insira o Cloud Storage URI. Não é possível incluir vários URIs na IU da Web do BigQuery, mas há compatibilidade com caracteres curinga. O bucket do Cloud Storage precisa estar no mesmo local que o conjunto de dados que contém a tabela que você está criando.
    • Em File format, selecione Parquet.
  4. Na seção Destination Table:

    • Em Table name, escolha o conjunto de dados apropriado e, no campo de nome da tabela, insira um nome para a tabela que você está criando no BigQuery.
    • Verifique se Table type está definido como Native table.
  5. Na seção Schema, nenhuma ação é necessária. O esquema é descrito automaticamente nos arquivos Parquet.

  6. (Opcional) Na seção Options:

    • Em Number of errors allowed, aceite o valor padrão 0 ou insira o número máximo de linhas contendo erros que podem ser ignorados. Se o número de linhas com erros exceder esse valor, o job exibirá uma mensagem invalid e falhará.
    • Em Write preference, selecione Write if empty. Essa opção cria uma nova tabela e carrega seus dados nela.
    • Para particionar a tabela:
      • Em Partitioning Type, clique em None e escolha Day.
      • Em Partitioning Field:
      • Para criar uma tabela particionada, escolha uma coluna DATE ou TIMESTAMP. Essa opção ficará indisponível se o esquema não incluir uma coluna DATE ou TIMESTAMP.
      • Para criar uma tabela particionada por tempo de ingestão, use o valor padrão: _PARTITIONTIME.
      • Clique na caixa Require partition filter para solicitar que os usuários incluam uma cláusula WHERE que especifique as partições a serem consultadas. A exigência de um filtro de particionamento pode reduzir os custos e melhorar o desempenho. Para mais informações, veja Como consultar tabelas particionadas. Essa opção ficará indisponível se Partitioning type estiver definido como None.
    • Para inserir a tabela em um cluster, insira até quatro nomes de campo na caixa Clustering fields.
    • Em Destination encryption, escolha Customer-managed encryption para usar uma chave do Cloud Key Management Service a fim de criptografar a tabela. Se você optar pela configuração Default, o BigQuery criptografará os dados em repouso usando uma chave gerenciada pelo Google.
  7. Clique em Create Table.

CLI

Use o comando bq load, especifique PARQUET usando a sinalização --source_format e inclua um URI do Cloud Storage. É possível incluir um único URI, uma lista de URIs separados por vírgulas ou um URI que contém um caractere curinga.

(Opcional) Forneça a sinalização --location e defina o valor para seu local.

Estas são outras sinalizações opcionais:

  • --max_bad_records: um número inteiro que especifica o número máximo de registros inválidos permitidos antes de uma falha em todo o job. O valor padrão é 0. No máximo, cinco erros de qualquer tipo são retornados, seja qual for o valor de --max_bad_records.
  • --time_partitioning_type: ativa o particionamento baseado em tempo na tabela e define o tipo de partição. Atualmente, o único valor possível é DAY, que gera uma partição por dia. Essa sinalização é opcional quando você cria uma tabela particionada em uma coluna DATE ou TIMESTAMP.
  • --time_partitioning_expiration: um número inteiro que especifica, em segundos, quando uma partição baseada em tempo precisa ser excluída. O prazo de validade é a soma da data UTC da partição mais o valor do número inteiro.
  • --time_partitioning_field: a coluna DATE ou TIMESTAMP usada para criar uma tabela particionada. Se o particionamento baseado em tempo estiver ativado sem esse valor, será criada uma tabela particionada por tempo de ingestão.
  • --require_partition_filter: quando ativada, esta opção exige que os usuários incluam uma cláusula WHERE que especifique as partições a serem consultadas. A exigência de um filtro de particionamento pode reduzir os custos e melhorar o desempenho. Para mais informações, veja Como consultar tabelas particionadas.
  • --clustering_fields: uma lista separada por vírgulas de até quatro nomes de colunas, usada para criar uma tabela em cluster. Só é possível usar essa sinalização com tabelas particionadas.
  • --destination_kms_key: a chave do Cloud KMS para criptografia dos dados da tabela.

    Para mais informações sobre tabelas particionadas, consulte:

    Para mais informações sobre tabelas em cluster, consulte:

    Para mais informações sobre criptografia de tabelas, consulte:

Para carregar dados Parquet no BigQuery, insira o comando a seguir:

    bq --location=location load \
    --source_format=format \
    dataset.table \
    path_to_source
    

Em que:

  • location é o local. A sinalização --location é opcional. Por exemplo, se estiver usando o BigQuery na região de Tóquio, defina o valor da sinalização como asia-northeast1. Defina um valor padrão para a unidade usando o arquivo .bigqueryr.
  • format é PARQUET.
  • dataset é um conjunto de dados atual.
  • table é o nome da tabela em que os dados serão carregados.
  • path_to_source é um URI do Cloud Storage totalmente qualificado ou uma lista de URIs separada por vírgulas. Os caracteres curinga também são compatíveis.

Exemplos:

O comando a seguir carrega dados de gs://mybucket/mydata.parquet em uma tabela chamada mytable em mydataset.

    bq load \
        --source_format=PARQUET \
        mydataset.mytable \
        gs://mybucket/mydata.parquet
    

O comando a seguir carrega dados de gs://mybucket/mydata.parquet em uma tabela particionada por tempo de ingestão chamada mytable em mydataset.

    bq load \
        --source_format=PARQUET \
        --time_partitioning_type=DAY \
        mydataset.mytable \
        gs://mybucket/mydata.parquet
    

O comando a seguir carrega dados de gs://mybucket/mydata.parquet em uma tabela particionada chamada mytable em mydataset. A tabela é particionada na coluna mytimestamp.

    bq load \
        --source_format=PARQUET \
        --time_partitioning_field mytimestamp \
        mydataset.mytable \
        gs://mybucket/mydata.parquet
    

O seguinte comando carrega dados de vários arquivos em gs://mybucket/ em uma tabela chamada mytable em mydataset. O URI do Cloud Storage usa um caractere curinga.

    bq load \
        --source_format=PARQUET \
        mydataset.mytable \
        gs://mybucket/mydata*.parquet
    

O seguinte comando carrega dados de vários arquivos em gs://mybucket/ em uma tabela chamada mytable em mydataset. O comando inclui uma lista separada por vírgulas de URIs do Cloud Storage com caracteres curinga.

    bq load \
        --source_format=PARQUET \
        mydataset.mytable \
        "gs://mybucket/00/*.parquet","gs://mybucket/01/*.parquet"
    

API

  1. Crie um job load que aponte para os dados de origem no Cloud Storage.

  2. (Opcional) Especifique o local na propriedade location da seção jobReference do recurso do job.

  3. A propriedade source URIs precisa ser totalmente qualificada no formato gs://bucket/object. Cada URI pode conter um caractere curinga "*".

  4. Especifique o formato de dados Parquet definindo a propriedade sourceFormat como PARQUET.

  5. Para verificar o status do job, chame jobs.get(job_id*), em que job_id é o código do job retornado pela solicitação inicial.

    • status.state = DONE mostra que o job foi concluído com sucesso.
    • A presença da propriedade status.errorResult mostra que houve falha na solicitação e o objeto incluirá informações que descrevem o erro. Quando há falha na solicitação, nenhuma tabela é criada, e os dados não são carregados.
    • A ausência de status.errorResult indica que o job foi concluído com sucesso. No entanto, é possível que haja alguns erros não fatais, como problemas ao importar algumas linhas. Os erros não fatais são listados na propriedade status.errors do objeto do job retornado.

Observações sobre a API:

  • Os jobs de carregamento são atômicos e consistentes. Se um deles falhar, nenhum dos dados estará disponível. Se um deles for bem-sucedido, todos os dados estarão disponíveis.

  • Como prática recomendada, gere um código exclusivo e transmita-o como jobReference.jobId ao chamar jobs.insert para criar um job de carregamento. Essa abordagem é mais resistente a falhas de rede porque o cliente pode pesquisar ou tentar novamente com o ID do job conhecido.

  • Chamar jobs.insert em um determinado ID de job é idempotente. É possível tentar quantas vezes quiser com o mesmo ID do job e, no máximo, uma das operações será bem-sucedida.

Go

Antes de testar esta amostra, siga as instruções de configuração do Go no Guia de início rápido do BigQuery: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API BigQuery Go (em inglês).

import (
    	"context"
    	"fmt"

    	"cloud.google.com/go/bigquery"
    )

    // importParquet demonstrates loading Apache Parquet data from Cloud Storage into a table.
    func importParquet(projectID, datasetID, tableID string) error {
    	// projectID := "my-project-id"
    	// datasetID := "mydataset"
    	// tableID := "mytable"
    	ctx := context.Background()
    	client, err := bigquery.NewClient(ctx, projectID)
    	if err != nil {
    		return fmt.Errorf("bigquery.NewClient: %v", err)
    	}
    	defer client.Close()

    	gcsRef := bigquery.NewGCSReference("gs://cloud-samples-data/bigquery/us-states/us-states.parquet")
    	gcsRef.SourceFormat = bigquery.Parquet
    	gcsRef.AutoDetect = true
    	loader := client.Dataset(datasetID).Table(tableID).LoaderFrom(gcsRef)

    	job, err := loader.Run(ctx)
    	if err != nil {
    		return err
    	}
    	status, err := job.Wait(ctx)
    	if err != nil {
    		return err
    	}

    	if status.Err() != nil {
    		return fmt.Errorf("job completed with error: %v", status.Err())
    	}
    	return nil
    }
    

Java

Antes de testar esta amostra, siga as instruções de configuração do Java no Guia de início rápido do BigQuery: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API BigQuery Java (em inglês).

import com.google.cloud.bigquery.BigQuery;
    import com.google.cloud.bigquery.BigQueryException;
    import com.google.cloud.bigquery.BigQueryOptions;
    import com.google.cloud.bigquery.FormatOptions;
    import com.google.cloud.bigquery.Job;
    import com.google.cloud.bigquery.JobInfo;
    import com.google.cloud.bigquery.LoadJobConfiguration;
    import com.google.cloud.bigquery.TableId;
    import java.math.BigInteger;

    public class LoadParquet {

      public static void runLoadParquet() {
        // TODO(developer): Replace these variables before running the sample.
        String datasetName = "MY_DATASET_NAME";
        loadParquet(datasetName);
      }

      public static void loadParquet(String datasetName) {
        try {
          // Initialize client that will be used to send requests. This client only needs to be created
          // once, and can be reused for multiple requests.
          BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

          String sourceUri = "gs://cloud-samples-data/bigquery/us-states/us-states.parquet";
          TableId tableId = TableId.of(datasetName, "us_states");

          LoadJobConfiguration configuration =
              LoadJobConfiguration.builder(tableId, sourceUri)
                  .setFormatOptions(FormatOptions.parquet())
                  .build();

          // For more information on Job see:
          // https://googleapis.dev/java/google-cloud-clients/latest/index.html?com/google/cloud/bigquery/package-summary.html
          // Load the table
          Job job = bigquery.create(JobInfo.of(configuration));

          // Blocks until this load table job completes its execution, either failing or succeeding.
          Job completedJob = job.waitFor();
          if (completedJob == null) {
            System.out.println("Job not executed since it no longer exists.");
            return;
          } else if (completedJob.getStatus().getError() != null) {
            System.out.println(
                "BigQuery was unable to load the table due to an error: \n"
                    + job.getStatus().getError());
            return;
          }

          // Check number of rows loaded into the table
          BigInteger numRows = bigquery.getTable(tableId).getNumRows();
          System.out.printf("Loaded %d rows. \n", numRows);

          System.out.println("GCS parquet loaded successfully.");
        } catch (BigQueryException | InterruptedException e) {
          System.out.println("GCS Parquet was not loaded. \n" + e.toString());
        }
      }
    }

Node.js

Antes de testar esta amostra, siga as instruções de configuração do Node.js no Guia de início rápido do BigQuery: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API BigQuery Node.js.

// Import the Google Cloud client libraries
    const {BigQuery} = require('@google-cloud/bigquery');
    const {Storage} = require('@google-cloud/storage');

    // Instantiate clients
    const bigquery = new BigQuery();
    const storage = new Storage();

    /**
     * This sample loads the Parquet file at
     * https://storage.googleapis.com/cloud-samples-data/bigquery/us-states/us-states.parquet
     *
     * TODO(developer): Replace the following lines with the path to your file.
     */
    const bucketName = 'cloud-samples-data';
    const filename = 'bigquery/us-states/us-states.parquet';

    async function loadTableGCSParquet() {
      // Imports a GCS file into a table with Parquet source format.

      /**
       * TODO(developer): Uncomment the following lines before running the sample.
       */
      // const datasetId = 'my_dataset';
      // const tableId = 'my_table';

      // Configure the load job. For full list of options, see:
      // https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#JobConfigurationLoad
      const metadata = {
        sourceFormat: 'PARQUET',
        location: 'US',
      };

      // Load data from a Google Cloud Storage file into the table
      const [job] = await bigquery
        .dataset(datasetId)
        .table(tableId)
        .load(storage.bucket(bucketName).file(filename), metadata);

      // load() waits for the job to finish
      console.log(`Job ${job.id} completed.`);

      // Check the job's status for errors
      const errors = job.status.errors;
      if (errors && errors.length > 0) {
        throw errors;
      }
    }

PHP

Antes de testar esta amostra, siga as instruções de configuração do PHP no Guia de início rápido do BigQuery: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API BigQuery PHP (em inglês).

use Google\Cloud\BigQuery\BigQueryClient;
    use Google\Cloud\Core\ExponentialBackoff;

    /** Uncomment and populate these variables in your code */
    // $projectId  = 'The Google project ID';
    // $datasetId  = 'The BigQuery dataset ID';

    // instantiate the bigquery table service
    $bigQuery = new BigQueryClient([
        'projectId' => $projectId,
    ]);
    $dataset = $bigQuery->dataset($datasetId);
    $table = $dataset->table('us_states');

    // create the import job
    $gcsUri = 'gs://cloud-samples-data/bigquery/us-states/us-states.parquet';
    $loadConfig = $table->loadFromStorage($gcsUri)->sourceFormat('PARQUET');
    $job = $table->runJob($loadConfig);
    // poll the job until it is complete
    $backoff = new ExponentialBackoff(10);
    $backoff->execute(function () use ($job) {
        print('Waiting for job to complete' . PHP_EOL);
        $job->reload();
        if (!$job->isComplete()) {
            throw new Exception('Job has not yet completed', 500);
        }
    });
    // check if the job has errors
    if (isset($job->info()['status']['errorResult'])) {
        $error = $job->info()['status']['errorResult']['message'];
        printf('Error running job: %s' . PHP_EOL, $error);
    } else {
        print('Data imported successfully' . PHP_EOL);
    }

Python

Antes de testar esta amostra, siga as instruções de configuração do Python no Guia de início rápido do BigQuery: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API BigQuery Python (em inglês).

Use o método Client.load_table_from_uri () (em inglês) para iniciar um job de carregamento do Cloud Storage. Para usar Parquet, defina a propriedade LoadJobConfig.source_format como a constante SourceFormat PARQUET e transfira a configuração do job como o argumento job_config para o método load_table_from_uri() (links em inglês).

# from google.cloud import bigquery
    # client = bigquery.Client()
    # dataset_id = 'my_dataset'

    dataset_ref = client.dataset(dataset_id)
    job_config = bigquery.LoadJobConfig()
    job_config.source_format = bigquery.SourceFormat.PARQUET
    uri = "gs://cloud-samples-data/bigquery/us-states/us-states.parquet"

    load_job = client.load_table_from_uri(
        uri, dataset_ref.table("us_states"), job_config=job_config
    )  # API request
    print("Starting job {}".format(load_job.job_id))

    load_job.result()  # Waits for table load to complete.
    print("Job finished.")

    destination_table = client.get_table(dataset_ref.table("us_states"))
    print("Loaded {} rows.".format(destination_table.num_rows))

Como substituir ou anexar a uma tabela com dados Parquet

Carregue dados complementares para uma tabela de arquivos de origem ou anexe resultados de consultas.

No Console e na IU da Web clássica do BigQuery, use a opção Gravar preferência para especificar a ação a ser executada ao carregar dados de um arquivo de origem ou de um resultado de consulta.

Você tem as seguintes opções ao carregar mais dados em uma tabela:

Opção de console Opção da IU da Web clássica Sinalização da CLI Property da API BigQuery Descrição
Gravar apenas se a tabela estiver vazia Write if empty Nenhuma WRITE_EMPTY Grava dados apenas se a tabela estiver vazia.
Anexar à tabela Append to table --noreplace ou --replace=false, se --[no]replace não for especificado, o padrão será anexado WRITE_APPEND (Padrão) Anexa os dados ao final da tabela.
Substituir tabela Overwrite table --replace ou --replace=true WRITE_TRUNCATE Apaga todos os dados da tabela antes de gravar os novos.

Se você carregar dados em uma tabela, o job de carregamento anexará esses dados ou substituirá a tabela.

É possível anexar ou substituir uma tabela:

  • usando o Console do Cloud ou a IU clássica da Web;
  • usando o comando bq load da CLI;
  • chamando o método da API jobs.insert e configurando um job load;
  • usando as bibliotecas de cliente.

Para anexar ou substituir uma tabela com dados Parquet:

Console

  1. Abra a IU da Web do BigQuery no Console do Cloud.
    Acessar o Console do Cloud

  2. Na seção Recursos do painel de navegação, abra o projeto e selecione um conjunto de dados.

  3. No lado direito da janela, no painel de detalhes, clique em Criar tabela. O processo para anexar e substituir dados em um job de carregamento é igual ao de criação de uma tabela.

    Criar tabela

  4. Na seção Origem da página Criar tabela, faça o seguinte:

    • Em Criar tabela de, selecione "Cloud Storage".

    • No campo de origem, procure ou insira o URI do Cloud Storage. Não é possível incluir vários URIs na IU da Web do BigQuery, mas há compatibilidade com caracteres curinga. O bucket do Cloud Storage precisa estar no mesmo local que o conjunto de dados que contém a tabela que você está anexando ou substituindo.

      Selecionar arquivo

    • Em Formato do arquivo, selecione Parquet.

  5. Na página Criar tabela, na seção Destino, faça o seguinte:

    • Em Nome do conjunto de dados, escolha o conjunto de dados apropriado.

      Selecionar conjunto de dados

    • No campo Nome da tabela, insira o nome da tabela que você está anexando ou substituindo no BigQuery.

    • Verifique se o Tipo de tabela está definido como Tabela nativa.

  6. Na seção Esquema, nenhuma ação é necessária. O esquema é descrito automaticamente nos arquivos Parquet.

  7. Em Configurações de partição e cluster, use os valores padrão. Não é possível anexar ou substituir uma tabela para convertê-la em uma tabela particionada ou em cluster. Além disso, o Console do Cloud não é compatível com a anexação ou substituição de tabelas particionadas ou em cluster em um job de carregamento.

  8. Clique em Opções avançadas.

    • Em Preferência de gravação, escolha Anexar à tabela ou Substituir tabela.
    • Em Número de erros permitidos, aceite o valor padrão 0 ou insira o número máximo de linhas contendo erros que podem ser ignorados. Se o número de linhas com erros exceder esse valor, o job exibirá uma mensagem invalid e falhará.
    • Em Valores desconhecidos, deixe a opção Ignorar valores desconhecidos desmarcada. Essa opção se refere apenas a arquivos CSV e JSON.
    • Em Criptografia, clique em Chave gerenciada pelo cliente para usar uma chave do Cloud Key Management Service. Se você optar pela configuração Chave gerenciada pelo Google, o BigQuery criptografará os dados em repouso.

      Substituir tabela

  9. Clique em Criar tabela.

IU clássica

  1. Acesse a IU da Web do BigQuery.
    Acessar a IU da Web do BigQuery

  2. No painel de navegação, passe o cursor do mouse sobre um conjunto de dados, clique no ícone de seta para baixo imagem do ícone de seta para baixo e selecione Create new table. O processo para anexar e substituir dados em um job de carregamento é igual ao de criação de uma tabela.

  3. Na página Create Table, na seção Source Data:

    • Em Location, selecione Cloud Storage e, no campo de origem, insira o Cloud Storage URI. Não é possível incluir vários URIs na IU, mas há compatibilidade com caracteres curinga. O bucket do Cloud Storage precisa estar no mesmo local que o conjunto de dados que contém a tabela que você está anexando ou substituindo.
    • Em File format, selecione Parquet.
  4. Na página Create Table, na seção Destination Table:

    • Em Table name, escolha o conjunto de dados apropriado e, no campo de nome, insira o nome da tabela que você está anexando ou substituindo.
    • Verifique se Table type está definido como Native table.
  5. Na seção Schema, nenhuma ação é necessária. As informações do esquema são autodescritas em arquivos Parquet.

  6. Na seção Options:

    • Em Number of errors allowed, aceite o valor padrão 0 ou insira o número máximo de linhas contendo erros que podem ser ignorados. Se o número de linhas com erros exceder esse valor, o job exibirá uma mensagem invalid e falhará.
    • Em Write preference, escolha Append to table ou Overwrite table.
    • Use os valores padrão de Partitioning Type, Partitioning Field, Require partition filter e Clustering Fields. Não é possível anexar ou substituir uma tabela para convertê-la em uma tabela particionada ou em cluster. Além disso, a IU da Web não é compatível com a anexação ou substituição de tabelas particionadas ou em cluster em um job de carregamento.
    • Em Destination encryption, escolha Customer-managed encryption para usar uma chave do Cloud Key Management Service a fim de criptografar a tabela. Se você optar pela configuração Default, o BigQuery criptografará os dados em repouso usando uma chave gerenciada pelo Google.
  7. Clique em Create Table.

CLI

Digite o comando bq load com a sinalização --replace para substituir a tabela. Use a sinalização --noreplace para anexar dados à tabela. Se nenhuma sinalização for especificada, o padrão será anexar os dados. Indique a sinalização --source_format e defina como PARQUET. Como os esquemas do Parquet são recuperados automaticamente dos dados de origem autodescritivos, você não precisa fornecer uma definição de esquema.

(Opcional) Forneça a sinalização --location e defina o valor para seu local.

Estas são outras sinalizações opcionais:

  • --max_bad_records: um número inteiro que especifica o número máximo de registros inválidos permitidos antes de uma falha em todo o job. O valor padrão é 0. No máximo, cinco erros de qualquer tipo são retornados, seja qual for o valor de --max_bad_records.
  • --destination_kms_key: a chave do Cloud KMS para criptografia dos dados da tabela.
    bq --location=location load \
    --[no]replace \
    --source_format=format \
    dataset.table \
    path_to_source
    

Em que:

  • location é o local. A sinalização --location é opcional. É possível definir um valor padrão para o local usando o arquivo .bigqueryrc.
  • format é PARQUET.
  • dataset é um conjunto de dados atual.
  • table é o nome da tabela em que os dados serão carregados.
  • path_to_source é um URI do Cloud Storage totalmente qualificado ou uma lista de URIs separada por vírgulas. Os caracteres curinga também são compatíveis.

Exemplos:

O comando a seguir carrega dados de gs://mybucket/mydata.parquet e substitui uma tabela chamada mytable em mydataset.

    bq load \
        --replace \
        --source_format=PARQUET \
        mydataset.mytable \
        gs://mybucket/mydata.parquet
    

O comando a seguir carrega dados de gs://mybucket/mydata.parquet e anexa dados a uma tabela chamada mytable em mydataset.

    bq load \
        --noreplace \
        --source_format=PARQUET \
        mydataset.mytable \
        gs://mybucket/mydata.parquet
    

Para informações sobre como anexar e substituir tabelas particionadas usando a CLI, consulte Como anexar e substituir dados de tabelas particionadas.

API

  1. Crie um job load que aponte para os dados de origem no Cloud Storage.

  2. (Opcional) Especifique o local na propriedade location da seção jobReference do recurso do job.

  3. A propriedade source URIs precisa ser totalmente qualificada no formato gs://bucket/object. É possível incluir vários URIs como uma lista separada por vírgulas. Os caracteres curinga também são compatíveis.

  4. Especifique o formato de dados definindo a propriedade configuration.load.sourceFormat como PARQUET.

  5. Especifique a preferência de gravação definindo a propriedade configuration.load.writeDisposition como WRITE_TRUNCATE ou WRITE_APPEND.

Go

Antes de testar esta amostra, siga as instruções de configuração do Go no Guia de início rápido do BigQuery: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API BigQuery Go (em inglês).

import (
    	"context"
    	"fmt"

    	"cloud.google.com/go/bigquery"
    )

    // importParquetTruncate demonstrates loading Apache Parquet data from Cloud Storage into a table
    // and overwriting/truncating existing data in the table.
    func importParquetTruncate(projectID, datasetID, tableID string) error {
    	// projectID := "my-project-id"
    	// datasetID := "mydataset"
    	// tableID := "mytable"
    	ctx := context.Background()
    	client, err := bigquery.NewClient(ctx, projectID)
    	if err != nil {
    		return fmt.Errorf("bigquery.NewClient: %v", err)
    	}
    	defer client.Close()

    	gcsRef := bigquery.NewGCSReference("gs://cloud-samples-data/bigquery/us-states/us-states.parquet")
    	gcsRef.SourceFormat = bigquery.Parquet
    	gcsRef.AutoDetect = true
    	loader := client.Dataset(datasetID).Table(tableID).LoaderFrom(gcsRef)
    	loader.WriteDisposition = bigquery.WriteTruncate

    	job, err := loader.Run(ctx)
    	if err != nil {
    		return err
    	}
    	status, err := job.Wait(ctx)
    	if err != nil {
    		return err
    	}

    	if status.Err() != nil {
    		return fmt.Errorf("job completed with error: %v", status.Err())
    	}
    	return nil
    }
    

Java

Antes de testar esta amostra, siga as instruções de configuração do Java no Guia de início rápido do BigQuery: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API BigQuery Java (em inglês).


    import com.google.cloud.bigquery.BigQuery;
    import com.google.cloud.bigquery.BigQueryException;
    import com.google.cloud.bigquery.BigQueryOptions;
    import com.google.cloud.bigquery.FormatOptions;
    import com.google.cloud.bigquery.Job;
    import com.google.cloud.bigquery.JobInfo;
    import com.google.cloud.bigquery.JobInfo.WriteDisposition;
    import com.google.cloud.bigquery.LoadJobConfiguration;
    import com.google.cloud.bigquery.TableId;
    import java.math.BigInteger;

    public class LoadParquetReplaceTable {

      public static void runLoadParquetReplaceTable() {
        // TODO(developer): Replace these variables before running the sample.
        String datasetName = "MY_DATASET_NAME";
        loadParquetReplaceTable(datasetName);
      }

      public static void loadParquetReplaceTable(String datasetName) {
        try {
          // Initialize client that will be used to send requests. This client only needs to be created
          // once, and can be reused for multiple requests.
          BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

          // Imports a GCS file into a table and overwrites table data if table already exists.
          // This sample loads CSV file at:
          // https://storage.googleapis.com/cloud-samples-data/bigquery/us-states/us-states.csv
          String sourceUri = "gs://cloud-samples-data/bigquery/us-states/us-states.parquet";
          TableId tableId = TableId.of(datasetName, "us_states");

          // For more information on LoadJobConfiguration see:
          // https://googleapis.dev/java/google-cloud-clients/latest/com/google/cloud/bigquery/LoadJobConfiguration.Builder.html
          LoadJobConfiguration configuration =
              LoadJobConfiguration.builder(tableId, sourceUri)
                  .setFormatOptions(FormatOptions.parquet())
                  // Set the write disposition to overwrite existing table data.
                  .setWriteDisposition(WriteDisposition.WRITE_TRUNCATE)
                  .build();

          // For more information on Job see:
          // https://googleapis.dev/java/google-cloud-clients/latest/index.html?com/google/cloud/bigquery/package-summary.html
          // Load the table
          Job job = bigquery.create(JobInfo.of(configuration));

          // Load data from a GCS parquet file into the table
          // Blocks until this load table job completes its execution, either failing or succeeding.
          Job completedJob = job.waitFor();
          if (completedJob == null) {
            System.out.println("Job not executed since it no longer exists.");
            return;
          } else if (completedJob.getStatus().getError() != null) {
            System.out.println(
                "BigQuery was unable to load into the table due to an error: \n"
                    + job.getStatus().getError());
            return;
          }

          // Check number of rows loaded into the table
          BigInteger numRows = bigquery.getTable(tableId).getNumRows();
          System.out.printf("Loaded %d rows. \n", numRows);

          System.out.println("GCS parquet overwrote existing table successfully.");
        } catch (BigQueryException | InterruptedException e) {
          System.out.println("Table extraction job was interrupted. \n" + e.toString());
        }
      }
    }

Node.js

Antes de testar esta amostra, siga as instruções de configuração do Node.js no Guia de início rápido do BigQuery: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API BigQuery Node.js.

// Import the Google Cloud client libraries
    const {BigQuery} = require('@google-cloud/bigquery');
    const {Storage} = require('@google-cloud/storage');

    // Instantiate clients
    const bigquery = new BigQuery();
    const storage = new Storage();

    /**
     * This sample loads the CSV file at
     * https://storage.googleapis.com/cloud-samples-data/bigquery/us-states/us-states.csv
     *
     * TODO(developer): Replace the following lines with the path to your file.
     */
    const bucketName = 'cloud-samples-data';
    const filename = 'bigquery/us-states/us-states.parquet';

    async function loadParquetFromGCSTruncate() {
      /**
       * Imports a GCS file into a table and overwrites
       * table data if table already exists.
       */

      /**
       * TODO(developer): Uncomment the following lines before running the sample.
       */
      // const datasetId = "my_dataset";
      // const tableId = "my_table";

      // Configure the load job. For full list of options, see:
      // https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#JobConfigurationLoad
      const metadata = {
        sourceFormat: 'PARQUET',
        // Set the write disposition to overwrite existing table data.
        writeDisposition: 'WRITE_TRUNCATE',
        location: 'US',
      };

      // Load data from a Google Cloud Storage file into the table
      const [job] = await bigquery
        .dataset(datasetId)
        .table(tableId)
        .load(storage.bucket(bucketName).file(filename), metadata);
      // load() waits for the job to finish
      console.log(`Job ${job.id} completed.`);

      // Check the job's status for errors
      const errors = job.status.errors;
      if (errors && errors.length > 0) {
        throw errors;
      }
    }

PHP

Antes de testar esta amostra, siga as instruções de configuração do PHP no Guia de início rápido do BigQuery: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API BigQuery PHP (em inglês).

use Google\Cloud\BigQuery\BigQueryClient;
    use Google\Cloud\Core\ExponentialBackoff;

    /** Uncomment and populate these variables in your code */
    // $projectId = 'The Google project ID';
    // $datasetId = 'The BigQuery dataset ID';
    // $tableID = 'The BigQuery table ID';

    // instantiate the bigquery table service
    $bigQuery = new BigQueryClient([
        'projectId' => $projectId,
    ]);
    $table = $bigQuery->dataset($datasetId)->table($tableId);

    // create the import job
    $gcsUri = 'gs://cloud-samples-data/bigquery/us-states/us-states.parquet';
    $loadConfig = $table->loadFromStorage($gcsUri)->sourceFormat('PARQUET')->writeDisposition('WRITE_TRUNCATE');
    $job = $table->runJob($loadConfig);

    // poll the job until it is complete
    $backoff = new ExponentialBackoff(10);
    $backoff->execute(function () use ($job) {
        print('Waiting for job to complete' . PHP_EOL);
        $job->reload();
        if (!$job->isComplete()) {
            throw new Exception('Job has not yet completed', 500);
        }
    });

    // check if the job has errors
    if (isset($job->info()['status']['errorResult'])) {
        $error = $job->info()['status']['errorResult']['message'];
        printf('Error running job: %s' . PHP_EOL, $error);
    } else {
        print('Data imported successfully' . PHP_EOL);
    }

Python

Antes de testar esta amostra, siga as instruções de configuração do Python no Guia de início rápido do BigQuery: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API BigQuery Python (em inglês).

Para substituir as linhas em uma tabela, defina a propriedade LoadJobConfig.write_disposition com a constante WriteDisposition WRITE_TRUNCATE (links em inglês).

# from google.cloud import bigquery
    # client = bigquery.Client()
    # table_ref = client.dataset('my_dataset').table('existing_table')

    job_config = bigquery.LoadJobConfig()
    job_config.write_disposition = bigquery.WriteDisposition.WRITE_TRUNCATE
    job_config.source_format = bigquery.SourceFormat.PARQUET
    uri = "gs://cloud-samples-data/bigquery/us-states/us-states.parquet"
    load_job = client.load_table_from_uri(
        uri, table_ref, job_config=job_config
    )  # API request
    print("Starting job {}".format(load_job.job_id))

    load_job.result()  # Waits for table load to complete.
    print("Job finished.")

    destination_table = client.get_table(table_ref)
    print("Loaded {} rows.".format(destination_table.num_rows))

Como carregar dados Parquet particionados do Hive

O BigQuery é compatível com o carregamento de dados Parquet particionados do hive e armazenados no Cloud Storage e preencherá as colunas particionadas do hive como colunas na tabela de destino gerenciada pelo BigQuery. Para mais informações, consulte Como carregar dados particionados externamente do Cloud Storage.

Conversões Parquet

O BigQuery converte tipos de dados Parquet nos seguintes tipos de dados do BigQuery:

Conversões de tipos

Tipo de Parquet Tipos convertidos do Parquet Tipo de dados do BigQuery
BOOLEAN NONE Booleano
INT32 NONE, UINT_8, UINT_16, UINT_32, INT_8, INT_16, INT_32 Inteiro
INT32 DECIMAL (consulte anotação DECIMAL) Numérico
INT32 DATE Data
INT64 NONE, UINT_64, INT_64 Inteiro
INT64 DECIMAL (consulte anotação DECIMAL) Numérico
INT64 TIMESTAMP_MILLIS Carimbo de data/hora
INT64 TIMESTAMP_MICROS Carimbo de data/hora
INT96 NONE Carimbo de data/hora
FLOAT NONE Ponto flutuante
DOUBLE NONE Ponto flutuante
BYTE_ARRAY NONE Bytes
BYTE_ARRAY UTF8 String
FIXED_LEN_BYTE_ARRAY DECIMAL (consulte anotação DECIMAL) Numérico
FIXED_LEN_BYTE_ARRAY NONE Bytes

Outras combinações de tipos Parquet e tipos convertidos não são compatíveis.

Anotação decimal

Os tipos Parquet com a anotação DECIMAL podem ter no máximo uma precisão de 38 (número total de dígitos) e no máximo uma escala de 9 (dígitos à direita do decimal). O número de dígitos inteiros, que é a precisão menos a escala, será no máximo 29. Por exemplo, DECIMAL(38, 9) é compatível porque a precisão é 38 e a escala é 9. Nesse exemplo, o número de dígitos inteiros é 29. DECIMAL(38, 5) não é compatível porque tem uma precisão de 38 e uma escala de 5. Nesse exemplo, o número de dígitos inteiros é 33.

Conversões de nome de coluna

O nome da coluna precisa conter apenas letras (a-z, A-Z), números (0-9) ou sublinhados (_) e começar com uma letra ou sublinhado. O comprimento máximo do nome da coluna é 128 caracteres. Não é possível usar estes prefixos nos nomes de coluna:

  • _TABLE_
  • _FILE_
  • _PARTITION

Os nomes de coluna duplicados não são permitidos, mesmo em caso de diferença de maiúsculas e minúsculas. Por exemplo, uma coluna chamada Column1 é considerada idêntica a uma coluna chamada column1.

Atualmente, não é possível carregar arquivos Parquet que contenham colunas com um ponto final (.) no nome da coluna.

Se o nome de uma coluna Parquet contiver outros caracteres (além de um ponto final), os caracteres serão substituídos por sublinhados. Os sublinhados à direita podem ser adicionados aos nomes das colunas para evitar colisões. Por exemplo, se um arquivo Parquet tiver duas colunas Column1 e column1, elas serão carregadas como Column1 e column1_, respectivamente.