Como criar tabelas particionadas

Nesta página, você aprende a criar tabelas particionadas no BigQuery. Para ter uma visão geral das tabelas particionadas, consulte Introdução às tabelas particionadas.

Permissões necessárias

Para criar uma tabela, você precisa ter pelo menos as seguintes permissões:

  • bigquery.tables.create para criar a tabela
  • bigquery.tables.updateData para gravar dados na tabela usando um job de carregamento, de consulta ou de cópia.
  • bigquery.jobs.create para executar jobs de consulta, de carregamento ou de cópia que gravem os dados na tabela

Outras permissões, como bigquery.tables.getData, são necessárias para acessar os dados que você está gravando na tabela.

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

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

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

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

Além disso, quando um usuário tem permissões bigquery.datasets.create e cria um conjunto de dados, ele recebe o acesso bigquery.dataOwner ao conjunto. O acesso bigquery.dataOwner permite que o usuário crie e atualize tabelas no conjunto de dados.

Para mais informações sobre papéis e permissões do IAM no BigQuery, consulte Papéis e permissões predefinidos.

Criar uma tabela particionada vazia

As etapas para criar uma tabela particionada no BigQuery são semelhantes à criação de uma tabela padrão, exceto pelo fato de que você especifica as opções de particionamento, junto com outras opções de tabela.

Criar uma tabela particionada por coluna de unidade de tempo

Para criar uma tabela particionada vazia por coluna de unidade de tempo com uma definição de esquema:

Console

  1. Abra a página do BigQuery no Console do Cloud.

    Acesse a página do BigQuery

  2. No painel Explorer, expanda o projeto e selecione um conjunto de dados.

  3. Expanda a opção Ações e clique em Abrir.

  4. No painel de detalhes, clique em Criar tabela .

  5. Na página Criar tabela, na seção Origem, selecione Tabela vazia.

  6. Na seção Destino:

    • Em Nome do conjunto de dados, escolha o conjunto apropriado.
    • No campo Nome da tabela, insira o nome da tabela.
    • Verifique se Table type está definido como Native table.
  7. Na seção Esquema, insira a definição do esquema. Verifique se o esquema inclui uma coluna DATE, TIMESTAMP ou DATETIME para a coluna de particionamento. Para mais informações, consulte Como especificar um esquema.

  8. Na seção Configurações de particionamento e cluster, na lista suspensa Particionamento, selecione Partição por campo e escolha a coluna de particionamento. Esta opção só estará disponível se o esquema contiver uma coluna DATE, TIMESTAMP ou DATETIME.

  9. Selecione o Tipo de particionamento para escolher particionamento diário, por hora, mensal ou anual.

  10. (Opcional) Para exigir um filtro de partição em todas as consultas desta tabela, marque a caixa de seleção Exigir filtro de partição. A exigência de um filtro de partição pode reduzir custos e melhorar o desempenho. Para mais informações, acesse Como consultar tabelas particionadas.

  11. Clique em Criar tabela.

SQL

Para criar uma tabela particionada por coluna de unidade de tempo, use a instrução CREATE TABLE com uma cláusula PARTITION BY.

O exemplo a seguir cria uma tabela com partições diárias baseadas na coluna transaction_date.

CREATE TABLE
  mydataset.newtable (transaction_id INT64, transaction_date DATE)
PARTITION BY
  transaction_date
OPTIONS(
  partition_expiration_days=3,
  require_partition_filter=true
)

O tipo de particionamento padrão das colunas DATE é o particionamento diário. Para especificar um tipo de particionamento diferente, inclua a função DATE_TRUNC na cláusula PARTITION BY. Por exemplo, a consulta a seguir cria uma tabela com partições mensais:

CREATE TABLE
  mydataset.newtable (transaction_id INT64, transaction_date DATE)
PARTITION BY
  DATE_TRUNC(transaction_date, MONTH)
OPTIONS(
  partition_expiration_days=3,
  require_partition_filter=true
)

Também é possível especificar uma coluna TIMESTAMP ou DATETIME como a coluna de particionamento. Nesse caso, inclua a função TIMESTAMP_TRUNC ou DATETIME_TRUNC na cláusula PARTITION BY para especificar o tipo de partição. Por exemplo, a instrução a seguir cria uma tabela com partições diárias com base em uma coluna TIMESTAMP:

CREATE TABLE
  mydataset.newtable (transaction_id INT64, transaction_ts TIMESTAMP)
PARTITION BY
  TIMESTAMP_TRUNC(transaction_ts, DAY)
OPTIONS(
  partition_expiration_days=3,
  require_partition_filter=true
)

Para informações sobre como executar consultas, consulte Como executar consultas interativas.

bq

Use o comando bq mk com a sinalização --table (ou atalho -t):

bq mk --table \
  --schema SCHEMA \
  --time_partitioning_field COLUMN \
  --time_partitioning_type UNIT_TIME \
  --time_partitioning_expiration EXPIRATION_TIME \
  --require_partition_filter=BOOLEAN
  PROJECT_ID:DATASET.TABLE

Substitua:

  • SCHEMA: uma definição de esquema no formato column:data_type,column:data_type ou o caminho para um arquivo de esquema JSON na máquina local. Para mais informações, consulte Como especificar um esquema.
  • COLUMN: o nome da coluna de particionamento. No esquema da tabela, essa coluna precisa ser um tipo TIMESTAMP, DATETIME ou DATE.
  • UNIT_TIME: o tipo de particionamento. Os valores compatíveis são DAY, HOUR, MONTH ou YEAR.
  • EXPIRATION_TIME: o prazo de validade das partições da tabela, em segundos. A sinalização --time_partitioning_expiration é opcional.
  • BOOLEAN: se for true, as consultas nesta tabela precisarão incluir um filtro de partição. A sinalização --require_partition_filter é opcional.
  • PROJECT_ID: o ID do projeto. Se omitido, o projeto padrão será usado.
  • DATASET: o nome de um conjunto de dados no projeto.
  • TABLE: o nome da tabela a ser criada.

Para outras opções de linha de comando, consulte bq mk.

No exemplo a seguir, criamos uma tabela denominada mytable que é particionada na coluna ts usando particionamento por hora. A validade da partição é de 259.200 segundos (três dias).

bq mk -t \
  --schema 'ts:TIMESTAMP,qtr:STRING,sales:FLOAT' \
  --time_partitioning_field ts \
  --time_partitioning_type HOUR \
  --time_partitioning_expiration 259200  \
  mydataset.mytable

API

Chame o método tables.insert com um recurso de tabela definido que especifique a property timePartitioning e a property schema.

Go

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

import (
	"context"
	"fmt"
	"time"

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

// createTablePartitioned demonstrates creating a table and specifying a time partitioning configuration.
func createTablePartitioned(projectID, datasetID, tableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydatasetid"
	// tableID := "mytableid"
	ctx := context.Background()

	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	sampleSchema := bigquery.Schema{
		{Name: "name", Type: bigquery.StringFieldType},
		{Name: "post_abbr", Type: bigquery.IntegerFieldType},
		{Name: "date", Type: bigquery.DateFieldType},
	}
	metadata := &bigquery.TableMetadata{
		TimePartitioning: &bigquery.TimePartitioning{
			Field:      "date",
			Expiration: 90 * 24 * time.Hour,
		},
		Schema: sampleSchema,
	}
	tableRef := client.Dataset(datasetID).Table(tableID)
	if err := tableRef.Create(ctx, metadata); err != nil {
		return err
	}
	return nil
}

Java

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

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.StandardSQLTypeName;
import com.google.cloud.bigquery.StandardTableDefinition;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TableInfo;
import com.google.cloud.bigquery.TimePartitioning;

// Sample to create a partition table
public class CreatePartitionedTable {

  public static void main(String[] args) {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    Schema schema =
        Schema.of(
            Field.of("name", StandardSQLTypeName.STRING),
            Field.of("post_abbr", StandardSQLTypeName.STRING),
            Field.of("date", StandardSQLTypeName.DATE));
    createPartitionedTable(datasetName, tableName, schema);
  }

  public static void createPartitionedTable(String datasetName, String tableName, Schema schema) {
    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();

      TableId tableId = TableId.of(datasetName, tableName);

      TimePartitioning partitioning =
          TimePartitioning.newBuilder(TimePartitioning.Type.DAY)
              .setField("date") //  name of column to use for partitioning
              .setExpirationMs(7776000000L) // 90 days
              .build();

      StandardTableDefinition tableDefinition =
          StandardTableDefinition.newBuilder()
              .setSchema(schema)
              .setTimePartitioning(partitioning)
              .build();
      TableInfo tableInfo = TableInfo.newBuilder(tableId, tableDefinition).build();

      bigquery.create(tableInfo);
      System.out.println("Partitioned table created successfully");
    } catch (BigQueryException e) {
      System.out.println("Partitioned table was not created. \n" + e.toString());
    }
  }
}

Node.js

Antes de testar essa amostra, siga as instruções de configuração para 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 library
const {BigQuery} = require('@google-cloud/bigquery');
const bigquery = new BigQuery();

async function createTablePartitioned() {
  // Creates a new partitioned table named "my_table" in "my_dataset".

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const datasetId = "my_dataset";
  // const tableId = "my_table";
  const schema = 'Name:string, Post_Abbr:string, Date:date';

  // For all options, see https://cloud.google.com/bigquery/docs/reference/v2/tables#resource
  const options = {
    schema: schema,
    location: 'US',
    timePartitioning: {
      type: 'DAY',
      expirationMS: '7776000000',
      field: 'date',
    },
  };

  // Create a new table in the dataset
  const [table] = await bigquery
    .dataset(datasetId)
    .createTable(tableId, options);
  console.log(`Table ${table.id} created with partitioning: `);
  console.log(table.metadata.timePartitioning);
}

Python

Antes de testar essa amostra, siga as instruções de configuração para 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 em Python.

# from google.cloud import bigquery
# client = bigquery.Client()
# project = client.project
# dataset_ref = bigquery.DatasetReference(project, 'my_dataset')

table_ref = dataset_ref.table("my_partitioned_table")
schema = [
    bigquery.SchemaField("name", "STRING"),
    bigquery.SchemaField("post_abbr", "STRING"),
    bigquery.SchemaField("date", "DATE"),
]
table = bigquery.Table(table_ref, schema=schema)
table.time_partitioning = bigquery.TimePartitioning(
    type_=bigquery.TimePartitioningType.DAY,
    field="date",  # name of column to use for partitioning
    expiration_ms=7776000000,
)  # 90 days

table = client.create_table(table)

print(
    "Created table {}, partitioned on column {}".format(
        table.table_id, table.time_partitioning.field
    )
)

Criar uma tabela particionada por tempo de processamento

Para criar uma tabela particionada vazia por tempo de processamento com uma definição de esquema:

Console

  1. Abra a página do BigQuery no Console do Cloud.

    Acesse a página do BigQuery

  2. No painel Explorer, expanda o projeto e selecione um conjunto de dados.

  3. Expanda a opção Ações e clique em Abrir.

  4. No painel de detalhes, clique em Criar tabela .

  5. Na página Criar tabela, na seção Origem, selecione Tabela vazia.

  6. Na seção Destino:

    • Em Nome do conjunto de dados, escolha o conjunto apropriado.
    • No campo Nome da tabela, insira o nome da tabela.
    • Verifique se Table type está definido como Native table.
  7. Na seção Esquema, insira a definição do esquema.

  8. Na seção Configurações de particionamento e cluster, em Particionamento, clique em Partição por tempo de processamento.

  9. (Opcional) Para exigir um filtro de partição em todas as consultas desta tabela, marque a caixa de seleção Exigir filtro de partição. A exigência de um filtro de partição pode reduzir custos e melhorar o desempenho. Para mais informações, acesse Como consultar tabelas particionadas.

  10. Clique em Criar tabela.

SQL

Para criar uma tabela particionada por tempo de processamento, use a instrução CREATE TABLE com uma cláusula PARTITION BY particionada por _PARTITIONTIME.

No exemplo a seguir, criamos uma tabela com partições diárias.

CREATE TABLE
  mydataset.newtable (transaction_id INT64)
PARTITION BY
  _PARTITIONDATE
OPTIONS(
  partition_expiration_days=3,
  require_partition_filter=true
)

O tipo de particionamento padrão para particionamento por tempo de processamento é o particionamento diário. Para especificar um tipo de particionamento diferente, inclua a função DATE_TRUNC na cláusula PARTITION BY. Por exemplo, a consulta a seguir cria uma tabela com partições mensais:

CREATE TABLE
  mydataset.newtable (transaction_id INT64)
PARTITION BY
  DATE_TRUNC(_PARTITIONTIME, MONTH)
OPTIONS(
  partition_expiration_days=3,
  require_partition_filter=true
)

Para informações sobre como executar consultas, consulte Como executar consultas interativas.

bq

Use o comando bq mk com a sinalização --table (ou atalho -t):

bq mk --table \
  --schema SCHEMA \
  --time_partitioning_type UNIT_TIME \
  --time_partitioning_expiration EXPIRATION_TIME \
  --require_partition_filter=BOOLEAN  \
  PROJECT_ID:DATASET.TABLE

Substitua:

  • SCHEMA: uma definição no formato column:data_type,column:data_type ou o caminho para um arquivo de esquema JSON na máquina local. Para mais informações, consulte Como especificar um esquema.
  • UNIT_TIME: o tipo de particionamento. Os valores compatíveis são DAY, HOUR, MONTH ou YEAR.
  • EXPIRATION_TIME: o prazo de validade das partições da tabela, em segundos. A sinalização --time_partitioning_expiration é opcional.
  • BOOLEAN: se for true, as consultas nesta tabela precisarão incluir um filtro de partição. A sinalização --require_partition_filter é opcional.
  • PROJECT_ID: o ID do projeto. Se omitido, o projeto padrão será usado.
  • DATASET: o nome de um conjunto de dados no projeto.
  • TABLE: o nome da tabela a ser criada.

Para outras opções de linha de comando, consulte bq mk.

No exemplo a seguir, criamos uma tabela particionada por tempo de processamento chamada mytable. A tabela tem particionamento diário, com validade de partição de 259.200 segundos (três dias).

bq mk -t \
  --schema qtr:STRING,sales:FLOAT,year:STRING \
  --time_partitioning_type DAY \
  --time_partitioning_expiration 259200 \
  mydataset.mytable

API

Chame o método tables.insert com um recurso de tabela definido que especifique a property timePartitioning e a property schema.

Criar uma tabela particionada por intervalo em números inteiros

Para criar uma tabela particionada vazia por intervalo de números inteiros com uma definição de esquema:

Console

  1. Abra a página do BigQuery no Console do Cloud.

    Acesse a página do BigQuery

  2. No painel Explorer, expanda o projeto e selecione um conjunto de dados.

  3. Expanda a opção Ações e clique em Abrir.

  4. No painel de detalhes, clique em Criar tabela .

  5. Na página Criar tabela, na seção Origem, selecione Tabela vazia.

  6. Na seção Destino:

    • Em Nome do conjunto de dados, escolha o conjunto apropriado.
    • No campo Nome da tabela, insira o nome da tabela.
    • Verifique se Table type está definido como Native table.
  7. Na seção Esquema, insira a definição do esquema. O esquema precisa incluir uma coluna INTEGER para a coluna de particionamento. Para mais informações, consulte Como especificar um esquema.

  8. Na seção Configurações de particionamento e cluster, na lista suspensa Particionamento, selecione Partição por campo e escolha a coluna de particionamento. Essa opção só estará disponível se o esquema contiver uma coluna INTEGER.

  9. Insira os valores para Início, Fim e Intervalo:

    • Início é o início do primeiro intervalo de partição (inclusivo).
    • Fim é o fim do último intervalo de partição (exclusivo).
    • Intervalo é a extensão de cada intervalo de partição.

    Valores fora desses intervalos entram em uma partição __UNPARTITIONED__ especial.

  10. (Opcional) Para exigir um filtro de partição em todas as consultas desta tabela, marque a caixa de seleção Exigir filtro de partição. A exigência de um filtro de partição pode reduzir custos e melhorar o desempenho. Para mais informações, acesse Como consultar tabelas particionadas.

  11. Clique em Criar tabela.

SQL

Para criar uma tabela particionada por intervalo de números inteiros, use a instrução CREATE TABLE com uma cláusula PARTITION BY.

No exemplo a seguir, criamos uma tabela que é particionada na coluna customer_id com início em 0, fim em 100 e intervalo em 10.

CREATE TABLE mydataset.newtable (customer_id INT64, date1 DATE)
PARTITION BY
  RANGE_BUCKET(customer_id, GENERATE_ARRAY(0, 100, 10))
OPTIONS(
  require_partition_filter=true
)

Para informações sobre como executar consultas, consulte Como executar consultas interativas.

bq

Use o comando bq mk com a sinalização --table (ou atalho -t):

bq mk \
  --schema schema \
  --range_partitioning=COLUMN_NAME,START,END,INTERVAL \
  --require_partition_filter=BOOLEAN  \
  PROJECT_ID:DATASET.TABLE

Substitua:

  • SCHEMA: uma definição de esquema in-line no formato column:data_type,column:data_type ou o caminho para o arquivo de esquema JSON na máquina local. Para mais informações, consulte Como especificar um esquema.
  • COLUMN_NAME: o nome da coluna de particionamento. No esquema da tabela, essa coluna precisa ser do tipo INTEGER.
  • START: o início do primeiro intervalo de partição (inclusivo).
  • END: o fim do último intervalo de partição (exclusivo).
  • INTERVAL: a extensão de cada intervalo de partição.
  • BOOLEAN: se for true, as consultas nesta tabela precisarão incluir um filtro de partição. A sinalização --require_partition_filter é opcional.
  • PROJECT_ID: o ID do projeto. Se omitido, o projeto padrão será usado.
  • DATASET: o nome de um conjunto de dados no projeto.
  • TABLE: o nome da tabela a ser criada.

Valores fora do intervalo de partição entram em uma partição __UNPARTITIONED__ especial.

Para outras opções de linha de comando, consulte bq mk.

No exemplo a seguir, criamos uma tabela denominada mytable, particionada na coluna customer_id.

bq mk -t \
  --schema 'customer_id:INTEGER,qtr:STRING,sales:FLOAT' \
  --range_partitioning=customer_id,0,100,10 \
  mydataset.mytable

API

Chame o método tables.insert com um recurso de tabela definido que especifique a property rangePartitioning e a property schema.

Java

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

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.RangePartitioning;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.StandardSQLTypeName;
import com.google.cloud.bigquery.StandardTableDefinition;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TableInfo;

// Sample to create a range partitioned table
public class CreateRangePartitionedTable {

  public static void main(String[] args) {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    Schema schema =
        Schema.of(
            Field.of("integerField", StandardSQLTypeName.INT64),
            Field.of("stringField", StandardSQLTypeName.STRING),
            Field.of("booleanField", StandardSQLTypeName.BOOL),
            Field.of("dateField", StandardSQLTypeName.DATE));
    createRangePartitionedTable(datasetName, tableName, schema);
  }

  public static void createRangePartitionedTable(
      String datasetName, String tableName, Schema schema) {
    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();

      TableId tableId = TableId.of(datasetName, tableName);

      // Note: The field must be a top- level, NULLABLE/REQUIRED field.
      // The only supported type is INTEGER/INT64
      RangePartitioning partitioning =
          RangePartitioning.newBuilder()
              .setField("integerField")
              .setRange(
                  RangePartitioning.Range.newBuilder()
                      .setStart(1L)
                      .setInterval(2L)
                      .setEnd(10L)
                      .build())
              .build();

      StandardTableDefinition tableDefinition =
          StandardTableDefinition.newBuilder()
              .setSchema(schema)
              .setRangePartitioning(partitioning)
              .build();
      TableInfo tableInfo = TableInfo.newBuilder(tableId, tableDefinition).build();

      bigquery.create(tableInfo);
      System.out.println("Range partitioned table created successfully");
    } catch (BigQueryException e) {
      System.out.println("Range partitioned table was not created. \n" + e.toString());
    }
  }
}

Node.js

Antes de testar essa amostra, siga as instruções de configuração para 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 library
const {BigQuery} = require('@google-cloud/bigquery');
const bigquery = new BigQuery();

async function createTableRangePartitioned() {
  // Creates a new integer range partitioned table named "my_table"
  // in "my_dataset".

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

  const schema = [
    {name: 'fullName', type: 'STRING'},
    {name: 'city', type: 'STRING'},
    {name: 'zipcode', type: 'INTEGER'},
  ];

  // To use integer range partitioning, select a top-level REQUIRED or
  // NULLABLE column with INTEGER / INT64 data type. Values that are
  // outside of the range of the table will go into the UNPARTITIONED
  // partition. Null values will be in the NULL partition.
  const rangePartition = {
    field: 'zipcode',
    range: {
      start: 0,
      end: 100000,
      interval: 10,
    },
  };

  // For all options, see https://cloud.google.com/bigquery/docs/reference/v2/tables#resource
  const options = {
    schema: schema,
    rangePartitioning: rangePartition,
  };

  // Create a new table in the dataset
  const [table] = await bigquery
    .dataset(datasetId)
    .createTable(tableId, options);

  console.log(`Table ${table.id} created with integer range partitioning: `);
  console.log(table.metadata.rangePartitioning);
}

Python

Antes de testar essa amostra, siga as instruções de configuração para 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 em Python.

from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

# TODO(developer): Set table_id to the ID of the table to create.
# table_id = "your-project.your_dataset.your_table_name"

schema = [
    bigquery.SchemaField("full_name", "STRING"),
    bigquery.SchemaField("city", "STRING"),
    bigquery.SchemaField("zipcode", "INTEGER"),
]

table = bigquery.Table(table_id, schema=schema)
table.range_partitioning = bigquery.RangePartitioning(
    # To use integer range partitioning, select a top-level REQUIRED /
    # NULLABLE column with INTEGER / INT64 data type.
    field="zipcode",
    range_=bigquery.PartitionRange(start=0, end=100000, interval=10),
)
table = client.create_table(table)  # Make an API request.
print(
    "Created table {}.{}.{}".format(table.project, table.dataset_id, table.table_id)
)

Criar uma tabela particionada com base no resultado de uma consulta

É possível criar uma tabela particionada com base em um resultado de consulta das seguintes maneiras:

  • Use a ferramenta de linha de comando bq ou a API BigQuery para definir uma tabela de destino para uma consulta. Quando a consulta é executada, o BigQuery grava os resultados na tabela de destino. Essa abordagem pode ser usada para qualquer tipo de particionamento.

  • No SQL, use uma instrução CREATE TABLE ... AS SELECT. É possível usar essa abordagem para criar uma tabela particionada por coluna de unidade de tempo ou intervalo de números inteiros, mas não por tempo de processamento.

SQL

Use a instrução CREATE TABLE com uma cláusula SELECT AS para a consulta. Inclua uma cláusula PARTITION BY para configurar o particionamento.

No exemplo a seguir, criamos uma tabela particionada na coluna transaction_date.

CREATE TABLE
  mydataset.newtable (transaction_id INT64, transaction_date DATE)
PARTITION BY
  transaction_date
AS SELECT transaction_id, transaction_date FROM mydataset.mytable

bq

Para criar uma tabela particionada a partir de uma consulta, use o comando bq query com as sinalizações --destination_table e --time_partitioning_type.

Particionamento de colunas por unidade de tempo

bq query \
  --use_legacy_sql=false \
  --destination_table TABLE_NAME \
  --time_partitioning_field COLUMN \
  --time_partitioning_type UNIT_TIME \
  'QUERY_STATEMENT'

Particionamento por tempo de processamento:

bq query \
  --use_legacy_sql=false \
  --destination_table TABLE_NAME \
  --time_partitioning_type UNIT_TIME \
  'QUERY_STATEMENT'

Particionamento por intervalo de números inteiros:

bq query \
  --use_legacy_sql=false \
  --destination_table PROJECT_ID:DATASET.TABLE \
  --range_partitioning COLUMN,START,END,INTERVAL \
  'QUERY_STATEMENT'

Substitua:

  • PROJECT_ID: o ID do projeto. Se omitido, o projeto padrão será usado.
  • DATASET: o nome de um conjunto de dados no projeto.
  • TABLE: o nome da tabela a ser criada.
  • COLUMN: o nome da coluna de particionamento.
  • UNIT_TIME: o tipo de particionamento. Os valores compatíveis são DAY, HOUR, MONTH ou YEAR.
  • START: o início do particionamento por intervalo, inclusivo.
  • END: o fim do particionamento por intervalo, exclusivo.
  • INTERVAL: a extensão de cada intervalo na partição.
  • QUERY_STATEMENT: a consulta usada para preencher a tabela.

No exemplo a seguir, criamos uma tabela que é particionada na coluna transaction_date usando particionamento mensal.

bq query \
  --use_legacy_sql=false
  --destination_table mydataset.newtable
  --time_partitioning_field transaction_id
  --time_partitioning_type MONTH
  'SELECT transaction_id, transaction_date FROM mydataset.mytable'

No exemplo a seguir, criamos uma tabela que é particionada na coluna customer_id usando o particionamento por intervalo de números inteiros.

bq query \
  --use_legacy_sql=false
  --destination_table mydataset.newtable
  --range_partitioning customer_id,0,100,10
  'SELECT * FROM mydataset.ponies'

Para tabelas particionadas por tempo de processamento, também é possível carregar dados em uma partição específica usando um decorador de partição. No exemplo a seguir, criamos uma nova tabela particionada por tempo de processamento e carregamos dados na partição 20180201 (1 de fevereiro de 2018):

bq query \
  --use_legacy_sql=false  \
  --time_partitioning_type=DAY
  --destination_table='newtable$20180201' \
  'SELECT * FROM mydataset.mytable'

API

Para salvar os resultados da consulta em uma tabela particionada, chame o método jobs.insert. Configure um job query. Especifique a tabela de destino na destinationTable. Especifique o particionamento na propriedade timePartitioning ou rangePartitioning.

Gravar dados em uma partição específica

Os decoradores de partição permitem que você grave dados em uma partição específica. Um decorador de partição tem o seguinte formato:

table_name$partition_id

O exemplo a seguir grava dados na partição 20160501 (1 de maio de 2016) de uma tabela atual, supondo que a tabela já esteja particionada por data:

bq load --source_format=CSV 'mydataset.mytable$20160501' data.csv

Você também pode gravar os resultados de uma consulta em uma partição específica:

bq query \
  --use_legacy_sql=false  \
  --destination_table='mytable$20160501' \
  --append_table=true \
  'SELECT * FROM mydataset.another_table'

Com o particionamento por tempo de processamento, é possível usar essa técnica para carregar dados mais antigos ou ajustar para fusos horários. Por exemplo, se você está no Horário padrão do Pacífico (PST, na sigla em inglês), é possível carregar dados gerados em 1 de maio de 2016 PST na partição dessa data usando o decorador de partição correspondente, $20160501. Por padrão, as partições de tempo de processamento são baseadas no horário UTC.

Para colunas particionadas por unidade de tempo e intervalo de números inteiros, o ID da partição especificado no decorador precisa corresponder aos dados que estão sendo gravados. Por exemplo, se a tabela for particionada em uma coluna DATE, o decorador precisará corresponder ao valor nela. Caso contrário, ocorrerá um erro. No entanto, se você souber de antemão que seus dados estão em uma única partição, especificar o decorador de partição poderá melhorar o desempenho de gravação.

Para mais informações sobre como carregar dados, consulte Introdução ao carregamento de dados no BigQuery.

Converter tabelas fragmentadas por data em tabelas particionadas por tempo de processamento

Se você já criou tabelas fragmentadas por data, é possível converter todo o conjunto de tabelas relacionadas em uma única tabela particionada por tempo de processamento usando o comando partition na ferramenta de linha de comando bq.

bq --location=LOCATION partition \
  --time_partitioning_type=PARTION_TYPE \
  --time_partitioning_expiration INTEGER \
  PROJECT_ID:SOURCE_DATASET.SOURCE_TABLE \
  PROJECT_ID:DESTINATION_DATASET.DESTINATION_TABLE

Substitua:

  • LOCATION: o nome do seu local. A sinalização --location é opcional.
  • PARTITION_TYPE: o tipo de partição. Os valores possíveis incluem DAY, HOUR, MONTH ou YEAR.
  • INTEGER: a validade da partição, em segundos. Não há valor mínimo. A validade é a soma da data UTC da partição com o valor do número inteiro. A sinalização time_partitioning_expiration é opcional.
  • PROJECT_ID: o ID do projeto
  • SOURCE_DATASET: o conjunto de dados que contém as tabelas fragmentadas por data.
  • SOURCE_TABLE: o prefixo das tabelas fragmentadas por data.
  • DESTINATION_DATASET: o conjunto de dados da nova tabela particionada.
  • DESTINATION_TABLE: o nome da tabela particionada a ser criada.

O comando partition não aceita sinalizações --label, --expiration ou --description. É possível adicionar rótulos, uma validade para a tabela e uma descrição à tabela particionada depois que ela for criada.

Quando você executa o comando partition, é criado um job de cópia no BigQuery que gera partições das tabelas fragmentadas.

No exemplo a seguir, criamos uma tabela particionada por tempo de processamento chamada mytable_partitioned a partir de um conjunto de tabelas fragmentadas por data com o prefixo sourcetable_. A nova tabela é particionada diariamente, com uma validade de partição de 259.200 segundos (3 dias).

bq partition \
--time_partitioning_type=DAY \
--time_partitioning_expiration 259200 \
mydataset.sourcetable_ \
mydataset.mytable_partitioned

Se as tabelas fragmentadas por data forem sourcetable_20180126 e sourcetable_20180127, esse comando criará estas partições: mydataset.mytable_partitioned$20180126 e mydataset.mytable_partitioned$20180127.

Próximas etapas

  • Para saber como gerenciar e atualizar tabelas particionadas, consulte esta página.
  • Para mais informações sobre como buscar tabelas particionadas, consulte esta página.