Como carregar dados de uma fonte local

Para carregar dados de uma fonte de dados legível, como sua máquina local, é possível usar o Console do GCP, a IU da Web do BigQuery, a CLI, a API ou as bibliotecas de cliente. Quando você carrega dados usando a IU da Web do BigQuery ou a CLI, um job de carregamento é criado automaticamente.

Para acessar tutoriais sobre o carregamento de arquivos CSV locais, consulte:

Limitações

O carregamento de dados a partir de uma fonte de dados local está sujeito às seguintes limitações:

  • Os caracteres curinga e as listas separadas por vírgulas não são compatíveis com o carregamento de arquivos de uma fonte de dados local. Os arquivos precisam ser carregados individualmente.
  • Ao usar a IU clássica da Web do BigQuery, os arquivos carregados de uma fonte de dados local precisam ter até 10 MB e conter menos de 16.000 linhas.

Como carregar dados de uma fonte local

Para carregar dados de uma fonte de dados local:

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 sobre um conjunto de dados e clique no ícone de seta para baixo imagem do ícone de seta para baixo. Em seguida, selecione Criar nova tabela. O processo de carregamento de dados é igual ao de criação de uma tabela vazia.

  3. Na página Criar tabela, na seção Dados de origem:

    • Em Local, selecione Carregamento de arquivo, clique em Escolher arquivo, navegue até o arquivo e clique em Abrir. Observe que os caracteres curinga e as listas separadas por vírgulas não são compatíveis com arquivos locais.
    • Em Formato de arquivo, selecione (CSV), JSON (delimitado por nova linha), Avro, Parquet ou ORC.
  4. Na página Criar tabela, na seção Tabela de destino:

    • Em Nome da tabela, 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 o Tipo de tabela está configurado como Tabela nativa.
  5. Na seção Esquema, insira a definição do esquema.

    • Em arquivos JSON e CSV, marque a opção Detecção automática para ativar a detecção automática de esquema. As informações de esquema são recuperadas dos arquivos Avro, Parquet e ORC usando os dados de origem.

      link da detecção automática

    • Outra opção é inserir informações do esquema manualmente:

      • Clique em Editar como texto e insira o esquema da tabela como uma matriz JSON:

        Adicionar esquema como uma matriz JSON

      • Use Adicionar campo para fazer a entrada do esquema manualmente.

        Adicionar esquema usando campos de adição

  6. Selecione os itens aplicáveis na seção Opções e clique em Criar tabela. Para informações sobre as opções disponíveis, consulte as opções CSV e JSON.

CLI

Use o comando bq load, especifique o source_format e inclua o caminho para o arquivo local. Forneça a sinalização --location e defina o valor do local.

bq --location=[LOCATION] load --source_format=[FORMAT] [DATASET].[TABLE] [PATH_TO_SOURCE] [SCHEMA]

em que:

  • [LOCATION] é o local. A sinalização --location será opcional se os dados estiverem no local multirregional US ou EU. Por exemplo, se você estiver usando o BigQuery na região de Tóquio, defina o valor da sinalização como asia-northeast1. É possível definir um valor padrão para o local usando o arquivo .bigqueryrc;
  • [FORMAT] é CSV, AVRO, PARQUET, ORC, ou NEWLINE_DELIMITED_JSON.
  • [DATASET] é um conjunto de dados existente;
  • [TABLE] é o nome da tabela em que você está carregando dados;
  • [PATH_TO_SOURCE] é o caminho para o arquivo local;
  • [SCHEMA] é um esquema válido. Ele pode ser um arquivo JSON local ou inserido in-line como parte do comando. Também é possível usar a sinalização --autodetect em vez de fornecer uma definição de esquema.

Além disso, é possível adicionar sinalizações de opções para controlar como o BigQuery analisa os dados. Por exemplo, use a sinalização --skip_leading_rows para ignorar linhas de cabeçalho em um arquivo CSV. Para mais informações, consulte as opções CSV e JSON.

Exemplos:

  • O comando a seguir carrega um arquivo JSON delimitado por nova linha (mydata.json) da máquina local em uma tabela chamada mytable em mydataset. O esquema é definido em um arquivo de esquema local chamado myschema.json. mydataset foi criado na multirregião US.

    bq --location=US load --source_format=NEWLINE_DELIMITED_JSON mydataset.mytable ./mydata.json ./myschema.json
    
  • O comando a seguir carrega um arquivo CSV (mydata.csv) da máquina local em uma tabela chamada mytable em mydataset. O esquema é definido em linha no formato [FIELD]:[DATA_TYPE], [FIELD]:[DATA_TYPE]. mydataset foi criado na região asia-northeast1.

    bq --location=asia-northeast1 load --source_format=CSV mydataset.mytable ./mydata.csv qtr:STRING,sales:FLOAT,year:STRING
    

    Observação: quando você especifica o esquema na linha de comando, não é possível incluir um tipo RECORD (STRUCT), inserir uma descrição de campo nem especificar o modo de campo. Todos os modos de campo assumem NULLABLE como padrão. Para incluir descrições de campo, modos e tipos RECORD, forneça um arquivo de esquema JSON.

  • O comando a seguir carrega um arquivo CSV (mydata.csv) da máquina local em uma tabela chamada mytable em mydataset. A detecção automática de esquema foi usada para definir o esquema, e mydataset foi criado na multirregião EU.

    bq --location=EU load --autodetect --source_format=CSV mydataset.mytable ./mydata.csv
    

C#

Antes de testar esta amostra, siga as instruções de configuração do C# no 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 C#.

O código a seguir demonstra como carregar um arquivo CSV local em uma nova tabela do BigQuery. Para carregar um arquivo local de outro formato, use a classe de opções de atualização para o formato apropriado da classe base JobCreationOptions em vez de UploadCsvOptions.

using Google.Cloud.BigQuery.V2;
using System;
using System.IO;

public class BigQueryLoadFromFile
{
    public void LoadFromFile(
        string projectId = "your-project-id",
        string datasetId = "your_dataset_id",
        string tableId = "your_table_id",
        string filePath = "path/to/file.csv"
    )
    {
        BigQueryClient client = BigQueryClient.Create(projectId);
        // Create job configuration
        var uploadCsvOptions = new UploadCsvOptions()
        {
            SkipLeadingRows = 1,  // Skips the file headers
            Autodetect = true
        };
        using (FileStream stream = File.Open(filePath, FileMode.Open))
        {
            // Create and run job
            // Note that there are methods available for formats other than CSV
            BigQueryJob job = client.UploadCsv(
                datasetId, tableId, null, stream, uploadCsvOptions);
            job.PollUntilCompleted();  // Waits for the job to complete.
            // Display the number of rows uploaded
            BigQueryTable table = client.GetTable(datasetId, tableId);
            Console.WriteLine(
                $"Loaded {table.Resource.NumRows} rows to {table.FullyQualifiedId}");
        }
    }
}

Go

Antes de testar esta amostra, siga as instruções de configuração do Go no 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.

O código a seguir demonstra como carregar um arquivo CSV local em uma nova tabela do BigQuery. Para carregar um arquivo local de outro formato, defina a propriedade DataFormat de NewReaderSource para o formato apropriado.

// To run this sample, you will need to create (or reuse) a context and
// an instance of the bigquery client.  For example:
// import "cloud.google.com/go/bigquery"
// ctx := context.Background()
// client, err := bigquery.NewClient(ctx, "your-project-id")
f, err := os.Open(filename)
if err != nil {
	return err
}
source := bigquery.NewReaderSource(f)
source.AutoDetect = true   // Allow BigQuery to determine schema.
source.SkipLeadingRows = 1 // CSV has a single header line.

loader := client.Dataset(datasetID).Table(tableID).LoaderFrom(source)

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

Java

Antes de testar esta amostra, siga as instruções de configuração do Java no 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 para Java.

O código a seguir demonstra como carregar um arquivo CSV local em uma nova tabela do BigQuery. Para carregar um arquivo local de outro formato, defina as FormatOptions para o formato apropriado.

TableId tableId = TableId.of(datasetName, tableName);
WriteChannelConfiguration writeChannelConfiguration =
    WriteChannelConfiguration.newBuilder(tableId).setFormatOptions(FormatOptions.csv()).build();
// The location must be specified; other fields can be auto-detected.
JobId jobId = JobId.newBuilder().setLocation(location).build();
TableDataWriteChannel writer = bigquery.writer(jobId, writeChannelConfiguration);
// Write data to writer
try (OutputStream stream = Channels.newOutputStream(writer)) {
  Files.copy(csvPath, stream);
}
// Get load job
Job job = writer.getJob();
job = job.waitFor();
LoadStatistics stats = job.getStatistics();
return stats.getOutputRows();

Node.js

Antes de testar esta amostra, siga as instruções de configuração do Node.js no 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 para Node.js.

O código a seguir demonstra como carregar um arquivo CSV local em uma nova tabela do BigQuery. Para carregar um arquivo local de outro formato, defina o parâmetro metadata da função load para o formato apropriado.

// Imports the Google Cloud client library
const {BigQuery} = require('@google-cloud/bigquery');

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

// Create a client
const bigquery = new BigQuery();

// Load data from a local file into the table
const [job] = await bigquery
  .dataset(datasetId)
  .table(tableId)
  .load(filename);

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 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 para PHP.

O código a seguir demonstra como carregar um arquivo CSV local em uma nova tabela do BigQuery. Para carregar um arquivo local de outro formato, defina sourceFormat para o formato apropriado.

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';
// $source     = 'The path to the CSV source file to import';

// instantiate the bigquery table service
$bigQuery = new BigQueryClient([
    'projectId' => $projectId,
]);
$dataset = $bigQuery->dataset($datasetId);
$table = $dataset->table($tableId);
// create the import job
$loadConfig = $table->load(fopen($source, 'r'))->sourceFormat('CSV');

$job = $table->runJob($loadConfig);
// poll the job until it is complete
$backoff = new ExponentialBackoff(10);
$backoff->execute(function () use ($job) {
    printf('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 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 para Python.

O código a seguir demonstra como carregar um arquivo CSV local em uma nova tabela do BigQuery. Para carregar um arquivo local de outro formato, defina a propriedade LoadJobConfig.source_format para o formato apropriado.

# from google.cloud import bigquery
# client = bigquery.Client()
# filename = '/path/to/file.csv'
# dataset_id = 'my_dataset'
# table_id = 'my_table'

dataset_ref = client.dataset(dataset_id)
table_ref = dataset_ref.table(table_id)
job_config = bigquery.LoadJobConfig()
job_config.source_format = bigquery.SourceFormat.CSV
job_config.skip_leading_rows = 1
job_config.autodetect = True

with open(filename, 'rb') as source_file:
    job = client.load_table_from_file(
        source_file,
        table_ref,
        location='US',  # Must match the destination dataset location.
        job_config=job_config)  # API request

job.result()  # Waits for table load to complete.

print('Loaded {} rows into {}:{}.'.format(
    job.output_rows, dataset_id, table_id))

Ruby

Antes de testar esta amostra, siga as instruções de configuração do Ruby no 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 para Ruby.

O código a seguir demonstra como carregar um arquivo CSV local em uma nova tabela do BigQuery. Para carregar um arquivo local de outro formato, defina o parâmetro format do método Table#load_job para o formato apropriado.

require "google/cloud/bigquery"

def load_from_file(
    dataset_id = "your_dataset_id",
    file_path = "path/to/file.csv"
  )
  bigquery = Google::Cloud::Bigquery.new
  dataset  = bigquery.dataset dataset_id
  table_id = "new_table_id"

  load_job = dataset.load_job table_id, file_path do |config|
    config.skip_leading = 1
    config.autodetect   = true
    # Must match the destination dataset location.
    config.location     = "US"
  end
  load_job.wait_until_done!  # Waits for table load to complete.

  table = dataset.table table_id
  puts "Loaded #{table.rows_count} rows into #{table.id}"
end

Como anexar ou substituir uma tabela usando um arquivo local

É possível carregar mais dados para uma tabela a partir de arquivos de origem ou anexando resultados de consultas. Se o esquema dos dados não corresponder ao da tabela ou partição de destino, você poderá substitui-lo ou atualizá-lo quando anexar à tabela.

Quando você atualiza o esquema anexando dados, o BigQuery permite:

  • adicionar novos campos;
  • relaxar os campos REQUIRED para NULLABLE.

Ao substituir uma tabela, o esquema é sempre alterado. Nesse processo, as atualizações de esquema não são restritas.

No Console ou na IU da Web clássica do BigQuery, use a opção de 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. A CLI e a API incluem as opções a seguir:

Opção do console Opção da IU clássica Sinalização da CLI Propriedade da API BigQuery Descrição
Gravar apenas se a tabela estiver vazia Gravar apenas se a tabela estiver vazia Nenhum WRITE_EMPTY Grava dados apenas se a tabela estiver vazia.
Anexar à tabela Anexar à tabela --noreplace ou --replace=false. Se --[no]replace não estiver especificado, o padrão será anexar WRITE_APPEND (Padrão) Anexa os dados ao final da tabela.
Substituir tabela Substituir tabela --replace ou --replace=true WRITE_TRUNCATE Apaga todos os dados existentes em uma tabela antes de gravar os novos dados.

Para carregar dados CSV, JSON, Avro, Parquet ou ORC de um arquivo local e anexá-los a uma tabela do BigQuery ou substitui-la, siga as etapas a seguir:

IU clássica

  1. Na página Criar tabela, na seção Dados de origem:
    • Em Local, selecione Carregamento de arquivo, clique em Escolher arquivo, navegue até o arquivo e clique em Abrir. Observe que os caracteres curinga e as listas separadas por vírgulas não são compatíveis com arquivos locais.
    • Em Formato de arquivo, selecione (CSV), JSON (delimitado por nova linha), Avro, Parquet ou ORC.
  2. Na página Criar tabela, na seção Tabela de destino:
    • Em Nome da tabela, escolha o conjunto de dados apropriado e insira o nome da tabela que você está anexando ou substituindo.
    • Verifique se o Tipo de tabela está configurado como Tabela nativa.
  3. Na seção Esquema, insira a definição do esquema. Para atualizar o esquema, adicione novos campos ou altere (relaxe) os campos de REQUIRED para NULLABLE.

    • Em arquivos JSON, é possível marcar a opção Detectar automaticamente para ativar a detecção automática do esquema.

      link da detecção automática

    • Outra opção é inserir informações do esquema manualmente:

      • Clique em Editar como texto e insira o esquema da tabela como uma matriz JSON:

        Adicionar esquema como uma matriz JSON

      • Use Adicionar campo para fazer a entrada do esquema manualmente.

        Adicionar esquema usando campos de adição

  4. Na seção Opções, em Preferência de gravação, escolha Gravar se estiver vazia, Anexar à tabela ou Substituir tabela.

    Adicionar esquema usando campos de adição

  5. Clique em Criar tabela.

Linha de comando

Insira 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. Forneça a sinalização --location e defina o valor do local.

Ao anexar ou substituir uma tabela, utilize a sinalização --schema_update_option para atualizar o esquema da tabela de destino com o esquema dos novos dados. É possível usar as opções a seguir com a sinalização --schema_update_option:

  • ALLOW_FIELD_ADDITION: adiciona novos campos ao esquema. Eles não podem ser REQUIRED.
  • ALLOW_FIELD_RELAXATION: altera os campos obrigatórios para "nullable". Repita essa opção para especificar uma lista de valores.
bq --location=[LOCATION] load --[no]replace [DATASET].[TABLE] [PATH_TO_SOURCE] [SCHEMA]

em que:

  • [LOCATION] é o local. A sinalização --location será opcional se os dados estiverem no local multirregional US ou EU. Por exemplo, se você estiver usando o BigQuery na região de Tóquio, defina o valor da sinalização como asia-northeast1. É possível definir um valor padrão para o local usando o arquivo .bigqueryrc;
  • [DATASET] é um conjunto de dados atual;
  • [TABLE] é o nome da tabela em que você está carregando dados;
  • [PATH_TO_SOURCE] é o caminho para o arquivo local. Observe que os caracteres curinga e as listas separadas por vírgulas não são compatíveis com arquivos locais;
  • [SCHEMA] é um esquema válido. Ele pode ser um arquivo JSON local ou inserido in-line como parte do comando. Também é possível usar a sinalização --autodetect em vez de fornecer uma definição de esquema.

Além disso, é possível adicionar sinalizações de opções JSON e CSV para controlar como o BigQuery analisa os dados.

Exemplos:

  • O comando a seguir carrega dados de mydata.json e substitui uma tabela chamada mytable em mydataset. Use a detecção automática de esquema para definir o esquema. mydataset foi criado na multirregião US.

    bq --location=US load --autodetect --replace --source_format=NEWLINE_DELIMITED_JSON mydataset.mytable ./mydata.json
    
  • O comando a seguir carrega dados de mydata.json e os anexa a uma tabela chamada mytable em mydataset. O esquema é definido usando um arquivo de esquema JSON: myschema.json. mydataset foi criado na multirregião US.

    bq --location=US load --autodetect --noreplace --source_format=NEWLINE_DELIMITED_JSON mydataset.mytable ./mydata.json ./myschema.json
    
  • O comando a seguir carrega dados de mydata.json e os anexa a uma tabela chamada mytable em mydataset. Um arquivo de esquema JSON local chamado myschema.json é usado. A definição do esquema contém novos campos não presentes na tabela de destino. mydataset foi criado na multirregião EU.

    bq --location=EU load --noreplace --schema_update_option=ALLOW_FIELD_ADDITION --source_format=NEWLINE_DELIMITED_JSON mydataset.mytable ./mydata.json ./myschema.json
    
  • O comando a seguir carrega dados de mydata.csv e os anexa a uma tabela chamada mytable em mydataset. Um arquivo de esquema JSON local chamado myschema.json é usado. A definição de esquema altera (relaxa) dois campos REQUIRED para NULLABLE. mydataset foi criado na região asia-northeast1.

    bq --location=asia-northeast1 load --noreplace --schema_update_option=ALLOW_FIELD_RELAXATION --source_format=NEWLINE_DELIMITED_JSON mydataset.mytable ./mydata.json ./myschema.json
    

Com o recurso de upload de mídia, a API do Google BigQuery pode ser usada para armazenar dados na nuvem e torná-los disponíveis para o servidor. É possível fazer upload de fotos, vídeos, arquivos PDF, arquivos ZIP e qualquer outro tipo de dado.

Opções de upload

Com a API Google BigQuery, é possível fazer upload de certos tipos de dados binários ou mídia. As características específicas dos dados que você pode enviar são especificadas na página de referência de qualquer método compatível com uploads de mídia:

  • Tamanho máximo do arquivo de upload: a quantidade máxima de dados que você pode armazenar com este método.
  • Tipos de mídia MIME aceitos: os tipos de dados binários que você pode armazenar usando este método.

Você pode fazer solicitações de upload de uma das seguintes maneiras. Especifique o método que você está usando com o parâmetro de solicitação uploadType.

  • Upload de várias partes: uploadType=multipart. Para transferência rápida de arquivos e metadados menores. Transfere o arquivo junto com os metadados que o descrevem, tudo em uma solicitação.
  • Upload recuperável: uploadType=resumable. Para transferência confiável, especialmente importante com arquivos maiores. Com esse método, você usa uma solicitação de inicialização de sessão, que opcionalmente pode incluir metadados. Essa é uma boa estratégia para usar na maioria dos aplicativos, já que também funciona para arquivos menores ao custo de uma solicitação HTTP extra por upload.

Ao fazer upload de mídias, use um URI especial. Na verdade, os métodos compatíveis com uploads de mídia têm dois pontos de extremidade de URI:

  • O URI /upload, para a mídia. O formato do ponto de extremidade de upload é o URI de recurso padrão com um prefixo "/upload". Use esse URI ao transferir os próprios dados de mídia. Por exemplo: POST /upload/bigquery/v2/projects/<projectId>/jobs
  • O URI de recurso padrão para os metadados. Se o recurso contiver campos de dados, esses campos serão usados para armazenar metadados que descrevem o arquivo enviado. Use esse URI ao criar ou atualizar valores de metadados. Por exemplo: POST /bigquery/v2/projects/<projectId>/jobs.

Upload de várias partes

Se você tiver metadados que deseje enviar juntamente com os dados para fazer upload, poderá fazer uma única solicitação multipart/related. Essa é uma boa opção se os dados que você está enviando forem pequenos o bastante para serem enviados novamente por completo se a conexão falhar.

Para usar o upload de várias partes, faça uma solicitação POST ao URI /upload do método e adicione o parâmetro de consulta uploadType=multipart. Por exemplo:

POST https://www.googleapis.com/upload/bigquery/v2/projects/<projectId>/jobs?uploadType=multipart

Os cabeçalhos HTTP de nível superior a serem usados durante uma solicitação de upload de várias partes incluem:

  • Content-Type. Defina como "multipart/related" e inclua a string de limite que você está usando para identificar as partes da solicitação.
  • Content-Length. Defina o número total de bytes no corpo da solicitação. A parte de mídia da solicitação precisa ser menor que o tamanho máximo de arquivo especificado para este método.

O corpo da solicitação é formatado como um tipo de conteúdo multipart/related [RFC2387] e tem exatamente duas partes. As partes são identificadas por uma string de limite, e a string de limite final é acompanhada por dois hifens.

Cada parte da solicitação de várias partes precisa de um cabeçalho Content-Type extra:

  1. Parte de metadados: precisa vir primeiro, e Content-Type precisa corresponder a um dos formatos de metadados aceitos.
  2. Parte de mídia: precisa vir em segundo, e Content-Type precisa corresponder a um dos tipos MIME de mídia aceitos pelo método.

Veja na referência da API uma lista com os tipos MIME de mídia aceitos por cada método e os limites de tamanho para arquivos carregados.

Observação: para criar ou atualizar apenas a porção de metadados, sem fazer o upload de dados associados, basta enviar uma solicitação POST ou PUT para o endpoint de recurso padrão: https://www.googleapis.com/bigquery/v2/projects/<projectId>/jobs.

Exemplo: upload de várias partes

O exemplo abaixo mostra uma solicitação de upload de várias partes para a API Google BigQuery.

POST /upload/bigquery/v2/projects/<projectId>/jobs?uploadType=multipart HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer your_auth_token
Content-Type: multipart/related; boundary=foo_bar_baz
Content-Length: number_of_bytes_in_entire_request_body

--foo_bar_baz
Content-Type: application/json; charset=UTF-8

{
  "configuration": {
    "load": {
      "sourceFormat": "NEWLINE_DELIMITED_JSON",
      "schema": {
        "fields": [
          {"name": "f1", "type": "STRING"},
          {"name": "f2", "type": "INTEGER"}
        ]
      },
      "destinationTable": {
        "projectId": "projectId",
        "datasetId": "datasetId",
        "tableId": "tableId"
      }
    }
  }
}

--foo_bar_baz
Content-Type: */*

CSV, JSON, AVRO, PARQUET, or ORC data
--foo_bar_baz--

Se a solicitação for bem-sucedida, o servidor retornará o código de status HTTP 200 OK juntamente com todos os metadados:

HTTP/1.1 200
Content-Type: application/json

{
  "configuration": {
    "load": {
      "sourceFormat": "NEWLINE_DELIMITED_JSON",
      "schema": {
        "fields": [
          {"name": "f1", "type": "STRING"},
          {"name": "f2", "type": "INTEGER"}
        ]
      },
      "destinationTable": {
        "projectId": "projectId",
        "datasetId": "datasetId",
        "tableId": "tableId"
      }
    }
  }
}

Upload recuperável

Para fazer upload de arquivos de dados de maneira mais confiável, você pode usar o protocolo de upload recuperável. Esse protocolo permite retomar uma operação de upload após uma falha de comunicação ter interrompido o fluxo de dados. Ele é especialmente útil se você estiver transferindo arquivos grandes e a probabilidade de uma interrupção de rede ou alguma outra falha de transmissão for alta, por exemplo, ao fazer upload a partir de um aplicativo de cliente móvel. Ele também pode reduzir o uso de largura de banda no caso de falhas de rede, porque você não precisa reiniciar uploads de arquivos grandes desde o início.

As etapas para usar o upload recuperável incluem:

  1. iniciar uma sessão recuperável. Faça uma solicitação inicial para o URI de upload que inclui os metadados, se houver.
  2. Salvar o URI da sessão recuperável. Salve o URI da sessão retornado na resposta da solicitação inicial. Use-o nas solicitações restantes dessa sessão.
  3. Fazer upload do arquivo. Envie o arquivo de mídia para o URI da sessão recuperável.

Além disso, os aplicativos que usam o upload recuperável precisam ter código para retomar um upload interrompido. Se um upload for interrompido, descubra quantos dados foram recebidos com êxito e retome o upload a partir desse ponto.

Observação: um URI de upload expira após uma semana.

Etapa 1: iniciar uma sessão recuperável

Para iniciar um upload recuperável, faça uma solicitação POST ao URI /upload do método e adicione o parâmetro de consulta uploadType=resumable. Por exemplo:

POST https://www.googleapis.com/upload/bigquery/v2/projects/<projectId>/jobs?uploadType=resumable

Para essa solicitação inicial, o corpo está vazio ou contém apenas os metadados. Você transferirá o conteúdo real do arquivo a ser enviado em solicitações subsequentes.

Use os seguintes cabeçalhos HTTP com a solicitação inicial:

  • X-Upload-Content-Type. Defina para o tipo MIME de mídia dos dados de upload a serem transferidos em solicitações subsequentes.
  • X-Upload-Content-Length. Defina o número de bytes de dados de upload a serem transferidos em solicitações subsequentes.  Se o tamanho for desconhecido no momento da solicitação, você poderá omitir esse cabeçalho.
  • Se fornecer metadados: Content-Type. Defina de acordo com o tipo de dados dos metadados.
  • Content-Length. Defina o número de bytes fornecidos no corpo dessa solicitação inicial. Isso não é obrigatório se você estiver usando a codificação de transferência em partes.

Consulte a referência da API para ver uma lista com os tipos MIME de mídia aceitos por cada método e os limites de tamanho para arquivos enviados.

Exemplo: solicitação de início de sessão recuperável

O exemplo a seguir mostra como iniciar uma sessão recuperável para a API Google BigQuery.

POST /upload/bigquery/v2/projects/<projectId>/jobs?uploadType=resumable HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer your_auth_token
Content-Length: 38
Content-Type: application/json; charset=UTF-8
X-Upload-Content-Type: */*
X-Upload-Content-Length: 2000000

{
  "configuration": {
    "load": {
      "sourceFormat": "NEWLINE_DELIMITED_JSON",
      "schema": {
        "fields": [
          {"name": "f1", "type": "STRING"},
          {"name": "f2", "type": "INTEGER"}
        ]
      },
      "destinationTable": {
        "projectId": "projectId",
        "datasetId": "datasetId",
        "tableId": "tableId"
      }
    }
  }
}

Observação: para uma solicitação de atualização recuperável inicial sem metadados, deixe o corpo da solicitação vazio e defina o cabeçalho Content-Length como 0.

A próxima seção descreve como lidar com a resposta.

Etapa 2: salvar o URI da sessão recuperável

Se a solicitação de início da sessão for bem-sucedida, o servidor da API responderá com um código de status HTTP 200 OK. Além disso, ele fornece um cabeçalho Location que especifica o URI da sessão recuperável. O cabeçalho Location, mostrado no exemplo abaixo, inclui uma parte do parâmetro de consulta upload_id que fornece o código de upload exclusivo a ser usado para essa sessão.

Exemplo: resposta de iniciação da sessão recuperável

Esta é a resposta à solicitação na Etapa 1:

HTTP/1.1 200 OK
Location: https://www.googleapis.com/upload/bigquery/v2/projects/<projectId>/jobs?uploadType=resumable&upload_id=xa298sd_sdlkj2
Content-Length: 0

O valor do cabeçalho Location, como mostrado na resposta de exemplo acima, é o URI de sessão que você usará como o ponto de extremidade HTTP para fazer upload do arquivo real ou consultar o status do upload.

Copie e salve o URI da sessão para que você possa usá-lo para solicitações subsequentes.

Etapa 3: fazer upload do arquivo

Para fazer upload do arquivo, envie uma solicitação PUT para o URI de upload recebido na etapa anterior. O formato da solicitação de upload é:

PUT session_uri

Os cabeçalhos HTTP a serem usados ao fazer as solicitações de upload de arquivos recuperáveis incluem Content-Length. Defina-o como o número de bytes que você está enviando nessa solicitação, que geralmente é o tamanho do arquivo de upload.

Exemplo: solicitação de upload de arquivo recuperável

Veja uma solicitação recuperável para enviar o arquivo inteiro CSV, JSON, AVRO ou PARQUET ou ORC de 2.000.000 bytes para o exemplo atual.

PUT https://www.googleapis.com/upload/bigquery/v2/projects/<projectId>/jobs?uploadType=resumable&upload_id=xa298sd_sdlkj2 HTTP/1.1
Content-Length: 2000000
Content-Type: */*

bytes 0-1999999

Se a solicitação for bem-sucedida, o servidor responderá com um HTTP 201 Created, juntamente com todos os metadados associados a esse recurso. Se a solicitação inicial da sessão recuperável tivesse sido PUT, a resposta de sucesso seria  200 OK para atualizar um recurso existente, juntamente com todos os metadados associados a esse recurso.

Se a solicitação de upload for interrompida, ou se você receber uma mensagem HTTP 503 Service Unavailable ou qualquer outra resposta 5xx do servidor, siga o procedimento descrito em retomar um upload interrompido.  


Como fazer upload do arquivo em partes

Com os uploads recuperáveis, você pode dividir um arquivo em partes e enviar várias solicitações para fazer upload de cada parte em sequência. Essa não é a abordagem preferida, já que há custos de desempenho associados às outras solicitações, e isso geralmente não é necessário. No entanto, talvez seja necessário usar a divisão em partes para reduzir a quantidade de dados transferidos em qualquer solicitação única. Isso é útil quando há um limite de tempo fixo para solicitações individuais, como acontece para determinadas classes de solicitações do Google App Engine. Isso também permite que você faça tarefas como fornecer indicações de progresso de upload para navegadores legados que não são compatíveis com progresso de upload por padrão.


Retomar um upload interrompido

Se uma solicitação de upload for encerrada antes de receber uma resposta ou se você receber uma mensagem HTTP 503 Service Unavailable do servidor, será preciso retomar o upload interrompido. Para isso:

  1. Solicite o status. Consulte o status atual do upload enviando uma solicitação PUT vazia para o URI de upload. Para essa solicitação, os cabeçalhos HTTP precisam incluir um cabeçalho Content-Range indicando que a posição atual no arquivo é desconhecida.  Por exemplo, defina o Content-Range como */2000000 se o comprimento total do arquivo for 2.000.000. Se você não souber o tamanho total do arquivo, defina o Content-Range como */*.

    Observação: você pode solicitar o status entre as partes, não apenas se o upload for interrompido. Isso é útil, por exemplo, se você quer mostrar as indicações do progresso de upload para navegadores legados.

  2. Verifique o número de bytes enviados. Processe a resposta da consulta de status. O servidor usa o cabeçalho Range na resposta para especificar quantos bytes recebeu até agora.  Por exemplo, um cabeçalho Range de 0-299999 indica que os primeiros 300.000 bytes do arquivo foram recebidos.
  3. Envie os dados restantes. Por fim, agora que você sabe de onde retomar a solicitação, envie os dados restantes ou a parte atual. Observe que você precisa tratar os dados restantes como uma parte separada em ambos os casos. Assim, você precisa enviar o cabeçalho Content-Range quando retomar o upload.
Exemplo: como retomar um upload interrompido

1) Solicite o status do upload.

A seguinte solicitação usa o cabeçalho Content-Range para indicar que a posição atual no arquivo de 2.000.000 bytes é desconhecida.

PUT {session_uri} HTTP/1.1
Content-Length: 0
Content-Range: bytes */2000000

2) Extraia o número de bytes enviados até agora da resposta.

A resposta do servidor usa o cabeçalho Range para indicar que ele recebeu os primeiros 43 bytes do arquivo até agora. Use o valor superior do cabeçalho Range para determinar onde iniciar o upload retomado.

HTTP/1.1 308 Resume Incomplete
Content-Length: 0
Range: 0-42

Obervação: é possível que a resposta de status seja 201 Created ou 200 OK se o upload estiver concluído. Isso poderá acontecer se houver falha na conexão após todos os bytes terem sido enviados, mas antes de o cliente ter recebido uma resposta do servidor.

3) Retome o upload do ponto em que parou.

A seguinte solicitação retoma o upload enviando os bytes restantes do arquivo, começando pelo byte 43.

PUT {session_uri} HTTP/1.1
Content-Length: 1999957
Content-Range: bytes 43-1999999/2000000

bytes 43-1999999

Práticas recomendadas

Ao fazer upload de mídia, considere algumas práticas recomendadas relacionadas ao tratamento de erros.

  • Retome ou repita os uploads que falharem devido a interrupções na conexão ou a erros 5xx, incluindo:
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout
  • Use uma estratégia de retirada exponencial se algum erro de servidor 5xx for retornado ao retomar ou repetir solicitações de upload. Esses erros podem ocorrer se um servidor estiver ficando sobrecarregado. A retirada exponencial pode ajudar a aliviar esses tipos de problemas durante períodos de alto volume de solicitações ou tráfego de rede intenso.
  • Outros tipos de solicitações não podem ser tratados por retirada exponencial, mas você ainda pode repetir vários deles. Ao repetir essas solicitações, limite o número de repetições. Por exemplo, o código pode limitar a dez tentativas ou menos antes de informar um erro.
  • Lide com erros 404 Not Found ao fazer uploads recuperáveis iniciando o upload completo desde o início.

Retirada exponencial

A retirada exponencial é uma estratégia padrão de tratamento de erros para aplicativos de rede em que o cliente repete periodicamente uma solicitação com falha ao longo de um período de tempo crescente. Se um alto volume de solicitações ou o tráfego de rede intenso fizer com que o servidor retorne erros, a retirada exponencial pode ser uma boa estratégia para lidar com esses erros. Por outro lado, não é uma estratégia relevante para lidar com erros não relacionados ao volume de rede ou a tempos de resposta, como credenciais de autorização inválidas ou erros de arquivo não encontrado.

Usada corretamente, a retirada exponencial aumenta a eficiência do uso da largura de banda, reduz o número de solicitações necessárias para conseguir uma resposta bem-sucedida e maximiza a capacidade de solicitações em ambientes simultâneos.

O fluxo para implementação da retirada exponencial simples é o seguinte:

  1. Faça uma solicitação para a API.
  2. Receba uma resposta HTTP 503, que indica que você precisa repetir a solicitação.
  3. Aguarde 1 segundo + random_number_milliseconds e repita a solicitação.
  4. Receba uma resposta HTTP 503, que indica que você precisa repetir a solicitação.
  5. Aguarde 2 segundos + random_number_milliseconds e repita a solicitação.
  6. Receba uma resposta HTTP 503, que indica que você precisa repetir a solicitação.
  7. Aguarde 4 segundos + random_number_milliseconds e repita a solicitação.
  8. Receba uma resposta HTTP 503, que indica que você precisa repetir a solicitação.
  9. Aguarde 8 segundos + random_number_milliseconds e repita a solicitação.
  10. Receba uma resposta HTTP 503, que indica que você precisa repetir a solicitação.
  11. Aguarde 16 segundos + random_number_milliseconds e repita a solicitação.
  12. Pare. Informe ou registre um erro.

No fluxo acima, random_number_milliseconds é um número aleatório de milissegundos menor ou igual a 1.000. Isso é necessário, uma vez que a introdução de um pequeno atraso aleatório ajuda a distribuir a carga de maneira mais uniforme e evitar a possibilidade de falha do servidor. O valor de random_number_milliseconds precisa ser redefinido após cada espera.

Observação: a espera é sempre (2 ^ n) + random_number_milliseconds, em que n é um número inteiro monótono crescente inicialmente definido como 0. O número inteiro n é incrementado em 1 para cada iteração (cada solicitação).

O algoritmo é definido para terminar quando n for 5. Esse limite impede que os clientes fiquem tentando infinitamente e resulta em um atraso total de cerca de 32 segundos antes de uma solicitação ser considerada "um erro irrecuperável". Um número máximo maior de tentativas não será um problema, especialmente se um upload longo estiver em andamento. No entanto, seja razoável e limite o atraso de repetição a menos de um minuto.

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Precisa de ajuda? Acesse nossa página de suporte.