Modifica esquemas de tabla

En este documento, se describe cómo cambiar las definiciones de esquema para tablas de BigQuery existentes.

Puedes hacer la mayoría de las modificaciones de esquema que se describen en este documento mediante declaraciones de lenguaje de definición de datos (DDL) de SQL. Estas declaraciones no generan cargos.

Puedes cambiar un esquema de tabla de todas las maneras que se describen en esta página si exportas los datos de tu tabla a Cloud Storage y, luego, cargas los datos en una tabla nueva con la definición de esquema modificada. Los trabajos de carga y exportación de BigQuery son gratuitos, pero se generan costos por almacenar los datos exportados en Cloud Storage. En las siguientes secciones, se describen otras formas de hacer varios tipos de modificaciones de esquema.

Agrega una columna

Puedes agregar columnas a la definición de esquema de una tabla existente a través de una de las siguientes opciones:

  • Agrega una columna vacía nueva.
  • Reemplaza una tabla por un trabajo de carga o consulta.
  • Adjunta datos a una tabla con un trabajo de carga o consulta.

Toda columna que agregas se debe adherir a las funciones de BigQuery para los nombres de consultas. Para obtener más información sobre cómo crear componentes de esquema, consulta Especifica un esquema.

Agregar una columna vacía

Si agregas columnas nuevas a un esquema de tabla existente, las columnas deben ser NULLABLE o REPEATED. No puedes agregar una columna REQUIRED a un esquema de tabla existente. Agregar una columna REQUIRED a un esquema de tabla existente en la API o la herramienta de línea de comandos de bq genera un error. Sin embargo, puedes crear una columna REQUIRED anidada como parte de un campo RECORD nuevo. Las columnas REQUIRED se pueden agregar solo cuando creas una tabla mientras cargas los datos o cuando creas una tabla vacía con una definición de esquema.

Para agregar columnas vacías a la definición de esquema de una tabla, sigue estos pasos:

Console

  1. En la consola de Google Cloud, ve a la página de BigQuery.

    Ir a BigQuery

  2. En el panel Explorador, expande el proyecto y conjunto de datos y, luego, elige la tabla.

  3. En el panel de detalles, haga clic en la pestaña Esquema.

  4. Haz clic en Editar esquema. Es posible que debas desplazarte para ver este botón.

  5. En la página Esquema actual, en Campos nuevos, haz clic en Agregar campo.

    • Para Nombre, escribe el nombre de la columna.
    • Para Tipo, elige el tipo de datos.
    • Para Modo, elige NULLABLE o REPEATED.
  6. Cuando termines de agregar columnas, haz clic en Guardar.

SQL

Usa la declaración DDL ALTER TABLE ADD COLUMN:

  1. En la consola de Google Cloud, ve a la página de BigQuery.

    Ir a BigQuery

  2. En el editor de consultas, escribe la siguiente sentencia:

    ALTER TABLE mydataset.mytable
    ADD COLUMN new_column STRING;

  3. Haz clic en Ejecutar.

Si deseas obtener información sobre cómo ejecutar consultas, visita Ejecuta una consulta interactiva.

bq

Ejecuta el comando bq update y proporciona un archivo de esquema JSON. Si la tabla que actualizas está en un proyecto que no es tu proyecto predeterminado, agrega el ID del proyecto al nombre del conjunto de datos en el siguiente formato: PROJECT_ID:DATASET.

bq update PROJECT_ID:DATASET.TABLE SCHEMA

Reemplaza lo siguiente:

  • PROJECT_ID: el ID de tu proyecto
  • DATASET: es el nombre del conjunto de datos que contiene la tabla que estás actualizando.
  • TABLE: Es el nombre de la tabla que estás actualizando.
  • SCHEMA: la ruta al archivo de esquema JSON en tu máquina local.

Cuando especificas un esquema intercalado, no puedes especificar la descripción, el modo y el tipo RECORD (STRUCT) de la columna. Todos los modos de columna están establecidos en NULLABLE de forma predeterminada. Como resultado, si agregas una nueva columna anidada a un RECORD, debes proporcionar un archivo de esquema JSON.

Si intentas agregar columnas con una definición de esquema intercalada, debes suministrar la definición de esquema completa que incluye las columnas nuevas. Debido a que no puedes especificar modos de columnas con una definición de esquema intercalada, la actualización cambia cualquier columna REPEATED existente a NULLABLE, lo que produce el siguiente error: BigQuery error in update operation: Provided Schema does not match Table PROJECT_ID:dataset.table. Field field has changed mode from REPEATED to NULLABLE.

El método recomendado para agregar columnas a una tabla existente mediante la herramienta de línea de comandos de bq es suministrar un archivo de esquema JSON.

Para agregar columnas vacías al esquema de una tabla con un archivo de esquema JSON, sigue estos pasos:

  1. Primero, ejecuta el comando bq show con la marca --schema y escribe el esquema de tabla existente en un archivo. Si la tabla que actualizas está en un proyecto que no es tu proyecto predeterminado, agrega el ID del proyecto al nombre del conjunto de datos en el siguiente formato: PROJECT_ID:DATASET.

    bq show \
    --schema \
    --format=prettyjson \
    PROJECT_ID:DATASET.TABLE > SCHEMA

    Reemplaza lo siguiente:

    • PROJECT_ID: el ID de tu proyecto
    • DATASET: es el nombre del conjunto de datos que contiene la tabla que estás actualizando.
    • TABLE: Es el nombre de la tabla que estás actualizando.
    • SCHEMA es el archivo de definición de esquema que se escribe en tu máquina local.

    Por ejemplo, para escribir la definición de esquema de mydataset.mytable en un archivo, escribe el siguiente comando. mydataset.mytable está en tu proyecto predeterminado.

       bq show \
       --schema \
       --format=prettyjson \
       mydataset.mytable > /tmp/myschema.json
    
  2. Abre el archivo del esquema en un editor de texto. El esquema debe verse de la manera siguiente:

    [
      {
        "mode": "REQUIRED",
        "name": "column1",
        "type": "STRING"
      },
      {
        "mode": "REQUIRED",
        "name": "column2",
        "type": "FLOAT"
      },
      {
        "mode": "REPEATED",
        "name": "column3",
        "type": "STRING"
      }
    ]
    
  3. Agrega las columnas nuevas al final de la definición del esquema. Si intentas agregar columnas nuevas en otra parte del arreglo, se muestra el siguiente error: BigQuery error in update operation: Precondition Failed.

    Con un archivo JSON, puedes especificar descripciones, modos NULLABLE o REPEATED, y tipos RECORD para columnas nuevas. Por ejemplo, mediante la definición de esquema del paso anterior, tu arreglo JSON nuevo se vería de la manera siguiente. En este ejemplo, se agrega una columna NULLABLE nueva llamada column4. column4 incluye una descripción.

      [
        {
          "mode": "REQUIRED",
          "name": "column1",
          "type": "STRING"
        },
        {
          "mode": "REQUIRED",
          "name": "column2",
          "type": "FLOAT"
        },
        {
          "mode": "REPEATED",
          "name": "column3",
          "type": "STRING"
        },
        {
          "description": "my new column",
          "mode": "NULLABLE",
          "name": "column4",
          "type": "STRING"
        }
      ]
      

    Para obtener más información sobre cómo trabajar con archivos de esquema JSON, consulta Especifica un archivo de esquema JSON.

  4. Después de actualizar tu archivo de esquema, ejecuta el comando siguiente para actualizar el esquema de la tabla. Si la tabla que actualizas está en un proyecto que no es tu proyecto predeterminado, agrega el ID del proyecto al nombre del conjunto de datos en el siguiente formato: PROJECT_ID:DATASET.

    bq update PROJECT_ID:DATASET.TABLE SCHEMA

    Reemplaza lo siguiente:

    • PROJECT_ID: el ID de tu proyecto
    • DATASET: es el nombre del conjunto de datos que contiene la tabla que estás actualizando.
    • TABLE: Es el nombre de la tabla que estás actualizando.
    • SCHEMA es el archivo de definición de esquema que se escribe en tu máquina local.

    Por ejemplo, escribe el siguiente comando para actualizar la definición de esquema de mydataset.mytable en tu proyecto predeterminado. La ruta al archivo de esquema en tu máquina local es /tmp/myschema.json.

    bq update mydataset.mytable /tmp/myschema.json
    

API

Llama al método tables.patch y usa la propiedad schema para agregar columnas vacías a la definición del esquema. Debido a que, con el método tables.update se reemplaza todo el recurso de tabla, es preferible usar el método tables.patch.

Go

Antes de probar este ejemplo, sigue las instrucciones de configuración para Go incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Go.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

import (
	"context"
	"fmt"

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

// updateTableAddColumn demonstrates modifying the schema of a table to append an additional column.
func updateTableAddColumn(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()

	tableRef := client.Dataset(datasetID).Table(tableID)
	meta, err := tableRef.Metadata(ctx)
	if err != nil {
		return err
	}
	newSchema := append(meta.Schema,
		&bigquery.FieldSchema{Name: "phone", Type: bigquery.StringFieldType},
	)
	update := bigquery.TableMetadataToUpdate{
		Schema: newSchema,
	}
	if _, err := tableRef.Update(ctx, update, meta.ETag); err != nil {
		return err
	}
	return nil
}

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración para Java incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Java.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

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.FieldList;
import com.google.cloud.bigquery.LegacySQLTypeName;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.StandardTableDefinition;
import com.google.cloud.bigquery.Table;
import java.util.ArrayList;
import java.util.List;

public class AddEmptyColumn {

  public static void runAddEmptyColumn() {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableId = "MY_TABLE_NAME";
    String newColumnName = "NEW_COLUMN_NAME";
    addEmptyColumn(newColumnName, datasetName, tableId);
  }

  public static void addEmptyColumn(String newColumnName, String datasetName, String tableId) {
    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();

      Table table = bigquery.getTable(datasetName, tableId);
      Schema schema = table.getDefinition().getSchema();
      FieldList fields = schema.getFields();

      // Create the new field/column
      Field newField = Field.of(newColumnName, LegacySQLTypeName.STRING);

      // Create a new schema adding the current fields, plus the new one
      List<Field> fieldList = new ArrayList<Field>();
      fields.forEach(fieldList::add);
      fieldList.add(newField);
      Schema newSchema = Schema.of(fieldList);

      // Update the table with the new schema
      Table updatedTable =
          table.toBuilder().setDefinition(StandardTableDefinition.of(newSchema)).build();
      updatedTable.update();
      System.out.println("Empty column successfully added to table");
    } catch (BigQueryException e) {
      System.out.println("Empty column was not added. \n" + e.toString());
    }
  }
}

Node.js

Antes de probar este ejemplo, sigue las instrucciones de configuración para Node.js incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Node.js.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.


// Import the Google Cloud client library and create a client
const {BigQuery} = require('@google-cloud/bigquery');
const bigquery = new BigQuery();

async function addEmptyColumn() {
  // Adds an empty column to the schema.

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const datasetId = 'my_dataset';
  // const tableId = 'my_table';
  const column = {name: 'size', type: 'STRING'};

  // Retrieve current table metadata
  const table = bigquery.dataset(datasetId).table(tableId);
  const [metadata] = await table.getMetadata();

  // Update table schema
  const schema = metadata.schema;
  const new_schema = schema;
  new_schema.fields.push(column);
  metadata.schema = new_schema;

  const [result] = await table.setMetadata(metadata);
  console.log(result.schema.fields);
}

Python

Antes de probar este ejemplo, sigue las instrucciones de configuración para Python incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Python.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

Agrega un objeto SchemaField nuevo a una copia de Table.schema y, a continuación, reemplaza el valor de la propiedad Table.schema por el esquema actualizado.
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 add an empty column.
# table_id = "your-project.your_dataset.your_table_name"

table = client.get_table(table_id)  # Make an API request.

original_schema = table.schema
new_schema = original_schema[:]  # Creates a copy of the schema.
new_schema.append(bigquery.SchemaField("phone", "STRING"))

table.schema = new_schema
table = client.update_table(table, ["schema"])  # Make an API request.

if len(table.schema) == len(original_schema) + 1 == len(new_schema):
    print("A new column has been added.")
else:
    print("The column has not been added.")

Agrega una columna anidada a una columna RECORD

Además de agregar columnas nuevas al esquema de una tabla, también puedes agregar columnas anidadas nuevas a una columna RECORD. El proceso para agregar una columna anidada nueva es similar al proceso para agregar una columna nueva.

Console

La consola de Google Cloud no admite agregar un nuevo campo anidado a una columna RECORD existente.

SQL

No se admite agregar un nuevo campo anidado a una columna RECORD existente mediante una instrucción de DDL de SQL.

bq

Ejecuta el comando bq update y proporciona un archivo de esquema JSON que agregue el campo anidado a la definición de esquema de la columna RECORD existente. Si la tabla que actualizas está en un proyecto que no es tu proyecto predeterminado, agrega el ID del proyecto al nombre del conjunto de datos en el siguiente formato: PROJECT_ID:DATASET.

bq update PROJECT_ID:DATASET.TABLE SCHEMA

Reemplaza lo siguiente:

  • PROJECT_ID: el ID de tu proyecto
  • DATASET: es el nombre del conjunto de datos que contiene la tabla que estás actualizando.
  • TABLE: Es el nombre de la tabla que estás actualizando.
  • SCHEMA: es la ruta al archivo de esquema JSON en tu máquina local.

Cuando especificas un esquema intercalado, no puedes especificar la descripción, el modo y el tipo RECORD (STRUCT) de la columna. Todos los modos de columna están establecidos en NULLABLE de forma predeterminada. Como resultado, si agregas una nueva columna anidada a un RECORD, debes proporcionar un archivo de esquema JSON.

Para agregar una columna anidada a RECORD mediante un archivo de esquema JSON, haz lo siguiente:

  1. Primero, ejecuta el comando bq show con la marca --schema y escribe el esquema de tabla existente en un archivo. Si la tabla que actualizas está en un proyecto que no es tu proyecto predeterminado, agrega el ID del proyecto al nombre del conjunto de datos en el siguiente formato: PROJECT_ID:DATASET.TABLE.

    bq show \
    --schema \
    --format=prettyjson \
    PROJECT_ID:DATASET.TABLE > SCHEMA

    Reemplaza lo siguiente:

    • PROJECT_ID: el ID de tu proyecto
    • DATASET: es el nombre del conjunto de datos que contiene la tabla que estás actualizando.
    • TABLE: Es el nombre de la tabla que estás actualizando.
    • SCHEMA es el archivo de definición de esquema que se escribe en tu máquina local.

    Por ejemplo, para escribir la definición de esquema de mydataset.mytable en un archivo, escribe el siguiente comando. mydataset.mytable está en tu proyecto predeterminado.

    bq show \
    --schema \
    --format=prettyjson \
    mydataset.mytable > /tmp/myschema.json
    
  2. Abre el archivo del esquema en un editor de texto. El esquema debe verse de la manera siguiente. En este ejemplo, column3 es una columna repetida anidada. Las columnas anidadas son nested1 y nested2. El arreglo fields enumera los campos anidados en column3.

    [
      {
        "mode": "REQUIRED",
        "name": "column1",
        "type": "STRING"
      },
      {
        "mode": "REQUIRED",
        "name": "column2",
        "type": "FLOAT"
      },
      {
        "fields": [
          {
            "mode": "NULLABLE",
            "name": "nested1",
            "type": "STRING"
          },
          {
            "mode": "NULLABLE",
            "name": "nested2",
            "type": "STRING"
          }
        ],
        "mode": "REPEATED",
        "name": "column3",
        "type": "RECORD"
      }
    ]
    
  3. Agrega la columna anidada nueva en el final del arreglo fields. En este ejemplo, nested3 es la columna anidada nueva.

      [
        {
          "mode": "REQUIRED",
          "name": "column1",
          "type": "STRING"
        },
        {
          "mode": "REQUIRED",
          "name": "column2",
          "type": "FLOAT"
        },
        {
          "fields": [
            {
              "mode": "NULLABLE",
              "name": "nested1",
              "type": "STRING"
            },
            {
              "mode": "NULLABLE",
              "name": "nested2",
              "type": "STRING"
            },
            {
              "mode": "NULLABLE",
              "name": "nested3",
              "type": "STRING"
            }
          ],
          "mode": "REPEATED",
          "name": "column3",
          "type": "RECORD"
        }
      ]
      

    Para obtener más información sobre cómo trabajar con archivos de esquema JSON, consulta Especifica un archivo de esquema JSON.

  4. Después de actualizar tu archivo de esquema, ejecuta el comando siguiente para actualizar el esquema de la tabla. Si la tabla que actualizas está en un proyecto que no es tu proyecto predeterminado, agrega el ID del proyecto al nombre del conjunto de datos en el siguiente formato: PROJECT_ID:DATASET.

    bq update PROJECT_ID:DATASET.TABLE SCHEMA

    Reemplaza lo siguiente:

    • PROJECT_ID: el ID de tu proyecto
    • DATASET: es el nombre del conjunto de datos que contiene la tabla que estás actualizando.
    • TABLE: Es el nombre de la tabla que estás actualizando.
    • SCHEMA: la ruta al archivo de esquema JSON en tu máquina local.

    Por ejemplo, escribe el siguiente comando para actualizar la definición de esquema de mydataset.mytable en tu proyecto predeterminado. La ruta al archivo de esquema en tu máquina local es /tmp/myschema.json.

    bq update mydataset.mytable /tmp/myschema.json
    

API

Llama al método tables.patch y usa la propiedad schema para agregar las columnas anidadas a tu definición de esquema. Debido a que, con el método tables.update se reemplaza todo el recurso de tabla, es preferible usar el método tables.patch.

Agrega columnas cuando reemplaces o agregues datos

Puedes agregar columnas nuevas a una tabla existente cuando cargas datos en esta y eliges reemplazar la tabla existente. Cuando reemplazas una tabla existente, el esquema de los datos que cargaste se usa para reemplazar el esquema de la tabla existente. Para obtener información sobre cómo reemplazar una tabla con un trabajo de carga, consulta el documento para el formato de tus datos:

Agrega columnas en un trabajo de anexo de carga

Puedes agregar columnas a una tabla cuando le anexas datos en un trabajo de carga. El esquema nuevo se determina a través de uno de los siguientes elementos:

  • Detección automática (para archivos CSV y JSON)
  • Un esquema especificado en un archivo de esquema JSON (para archivos CSV y JSON)
  • Los datos fuente autodescriptivos de los archivos de exportación de Avro, ORC, Parquet y Datastore

Si especificas el esquema en un archivo JSON, las columnas nuevas se deben definir en él. Si faltan las definiciones nuevas de la columna, se muestra un error cuando intentas anexar los datos.

Cuando agregas columnas nuevas durante una operación de anexo, los valores en las columnas nuevas se establecen en NULL para las filas existentes.

Para agregar una columna nueva cuando anexas datos en una tabla durante un trabajo de carga, usa una de las siguientes opciones:

bq

Usa el comando bq load para cargar tus datos y especifica la marca --noreplace para indicar que anexas los datos a una tabla existente.

Si los datos que agregas están en formato CSV o JSON delimitado por saltos de línea, especifica la marca --autodetect para usar la detección automática de esquemas o suministra el esquema en un archivo de esquema JSON. Las columnas agregadas se pueden inferir de forma automática desde los archivos de exportación Avro o Datastore.

Establece la marca --schema_update_option en ALLOW_FIELD_ADDITION para indicar que los datos que anexas contienen nuevas columnas.

Si la tabla que anexas se encuentra en un conjunto de datos de un proyecto distinto a tu proyecto predeterminado, debes agregar el ID del proyecto al nombre del conjunto de datos en el siguiente formato: PROJECT_ID:DATASET.

Opcional: Proporciona la marca --location y configura el valor en tu ubicación.

Escribe el comando load de la siguiente manera:

bq --location=LOCATION load \
--noreplace \
--autodetect \
--schema_update_option=ALLOW_FIELD_ADDITION \
--source_format=FORMAT \
PROJECT_ID:DATASET.TABLE \
PATH_TO_SOURCE \
SCHEMA

Reemplaza lo siguiente:

  • LOCATION: El nombre de tu ubicación. La marca --location es opcional. Por ejemplo, si usas BigQuery en la región de Tokio, configura el valor de la marca como asia-northeast1. Puedes configurar un valor predeterminado para la ubicación con el archivo .bigqueryrc.
  • FORMAT: es el formato del esquema. NEWLINE_DELIMITED_JSON, CSV, AVRO, PARQUET, ORC o DATASTORE_BACKUP.
  • PROJECT_ID: el ID de tu proyecto
  • DATASET: Es el nombre del conjunto de datos que contiene la tabla.
  • TABLE: es el nombre de la tabla que crearás.
  • PATH_TO_SOURCE: un URI de Cloud Storage completamente calificado, una lista de URI separada por comas o la ruta a un archivo de datos en tu máquina local.
  • SCHEMA: la ruta a un archivo de esquema JSON local. Solo se requiere un archivo de esquema para los archivos CSV y JSON cuando --autodetect no se especifica. Los esquemas de Avro y Datastore se infieren de los datos de origen.

Ejemplos:

Escribe el siguiente comando para anexar un archivo de datos de Avro local, /tmp/mydata.avro, a mydataset.mytable mediante un trabajo de carga. Debido a que los esquemas se pueden deducir de forma automática de los datos de Avro, no es necesario usar la marca --autodetect. mydataset está en tu proyecto predeterminado.

bq load \
--noreplace \
--schema_update_option=ALLOW_FIELD_ADDITION \
--source_format=AVRO \
mydataset.mytable \
/tmp/mydata.avro

Escribe el siguiente comando para anexar un archivo de datos JSON delimitado por saltos de línea en Cloud Storage a mydataset.mytable mediante un trabajo de carga. La marca --autodetect se usa para detectar las columnas nuevas. mydataset está en tu proyecto predeterminado.

bq load \
--noreplace \
--autodetect \
--schema_update_option=ALLOW_FIELD_ADDITION \
--source_format=NEWLINE_DELIMITED_JSON \
mydataset.mytable \
gs://mybucket/mydata.json

Escribe el siguiente comando para anexar un archivo de datos JSON delimitado por saltos de línea en Cloud Storage a mydataset.mytable mediante un trabajo de carga. El esquema que contiene las columnas nuevas se especifica en un archivo de esquema JSON local, /tmp/myschema.json. mydataset se encuentra en myotherproject, no en tu proyecto predeterminado.

bq load \
--noreplace \
--schema_update_option=ALLOW_FIELD_ADDITION \
--source_format=NEWLINE_DELIMITED_JSON \
myotherproject:mydataset.mytable \
gs://mybucket/mydata.json \
/tmp/myschema.json

API

Realiza una llamada al método jobs.insert. Configura un trabajo load y establece las propiedades siguientes:

  • Haz referencia a tus datos en Cloud Storage mediante la propiedad sourceUris.
  • Para especificar el formato de datos, configura la propiedad sourceFormat.
  • Especifica el esquema en la propiedad schema.
  • Especifica la opción de actualización del esquema con la propiedad schemaUpdateOptions.
  • Establece la disposición de escritura de la tabla de destino en WRITE_APPEND con la propiedad writeDisposition.

Go

Antes de probar este ejemplo, sigue las instrucciones de configuración para Go incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Go.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

import (
	"context"
	"fmt"
	"os"

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

// createTableAndWidenLoad demonstrates augmenting a table's schema to add a new column via a load job.
func createTableAndWidenLoad(projectID, datasetID, tableID, filename 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()

	sampleSchema := bigquery.Schema{
		{Name: "full_name", Type: bigquery.StringFieldType},
	}
	meta := &bigquery.TableMetadata{
		Schema: sampleSchema,
	}
	tableRef := client.Dataset(datasetID).Table(tableID)
	if err := tableRef.Create(ctx, meta); err != nil {
		return err
	}
	// Now, import data from a local file, but specify field additions are allowed.
	// Because the data has a second column (age), the schema is amended as part of
	// the load.
	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)
	loader.SchemaUpdateOptions = []string{"ALLOW_FIELD_ADDITION"}
	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
	}
	return nil
}

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración para Java incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Java.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

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.FormatOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobId;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.JobInfo.SchemaUpdateOption;
import com.google.cloud.bigquery.JobInfo.WriteDisposition;
import com.google.cloud.bigquery.LegacySQLTypeName;
import com.google.cloud.bigquery.LoadJobConfiguration;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.TableId;
import com.google.common.collect.ImmutableList;
import java.util.UUID;

public class AddColumnLoadAppend {

  public static void runAddColumnLoadAppend() throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    String sourceUri = "/path/to/file.csv";
    addColumnLoadAppend(datasetName, tableName, sourceUri);
  }

  public static void addColumnLoadAppend(String datasetName, String tableName, String sourceUri)
      throws Exception {
    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);

      // Add a new column to a BigQuery table while appending rows via a load job.
      // 'REQUIRED' fields cannot  be added to an existing schema, so the additional column must be
      // 'NULLABLE'.
      Schema newSchema =
          Schema.of(
              Field.newBuilder("name", LegacySQLTypeName.STRING)
                  .setMode(Field.Mode.REQUIRED)
                  .build(),
              // Adding below additional column during the load job
              Field.newBuilder("post_abbr", LegacySQLTypeName.STRING)
                  .setMode(Field.Mode.NULLABLE)
                  .build());

      LoadJobConfiguration loadJobConfig =
          LoadJobConfiguration.builder(tableId, sourceUri)
              .setFormatOptions(FormatOptions.csv())
              .setWriteDisposition(WriteDisposition.WRITE_APPEND)
              .setSchema(newSchema)
              .setSchemaUpdateOptions(ImmutableList.of(SchemaUpdateOption.ALLOW_FIELD_ADDITION))
              .build();

      // Create a job ID so that we can safely retry.
      JobId jobId = JobId.of(UUID.randomUUID().toString());
      Job loadJob = bigquery.create(JobInfo.newBuilder(loadJobConfig).setJobId(jobId).build());

      // 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 = loadJob.waitFor();

      // Check for errors
      if (completedJob == null) {
        throw new Exception("Job not executed since it no longer exists.");
      } else if (completedJob.getStatus().getError() != null) {
        // You can also look at queryJob.getStatus().getExecutionErrors() for all
        // errors, not just the latest one.
        throw new Exception(
            "BigQuery was unable to load into the table due to an error: \n"
                + loadJob.getStatus().getError());
      }
      System.out.println("Column successfully added during load append job");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Column not added during load append \n" + e.toString());
    }
  }
}

Node.js

Antes de probar este ejemplo, sigue las instrucciones de configuración para Node.js incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Node.js.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

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

// Instantiate client
const bigquery = new BigQuery();

async function addColumnLoadAppend() {
  // Adds a new column to a BigQuery table while appending rows via a load job.

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

  // In this example, the existing table contains only the 'Name', 'Age',
  // & 'Weight' columns. 'REQUIRED' fields cannot  be added to an existing
  // schema, so the additional column must be 'NULLABLE'.
  const schema = 'Name:STRING, Age:INTEGER, Weight:FLOAT, IsMagic:BOOLEAN';

  // Retrieve destination table reference
  const [table] = await bigquery
    .dataset(datasetId)
    .table(tableId)
    .get();
  const destinationTableRef = table.metadata.tableReference;

  // Set load job options
  const options = {
    schema: schema,
    schemaUpdateOptions: ['ALLOW_FIELD_ADDITION'],
    writeDisposition: 'WRITE_APPEND',
    destinationTable: destinationTableRef,
  };

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

  console.log(`Job ${job.id} completed.`);
  console.log(`New Schema:`);
  console.log(job.configuration.load.schema.fields);

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

Python

Antes de probar este ejemplo, sigue las instrucciones de configuración para Python incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Python.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

# from google.cloud import bigquery
# client = bigquery.Client()
# project = client.project
# dataset_ref = bigquery.DatasetReference(project, 'my_dataset')
# filepath = 'path/to/your_file.csv'

# Retrieves the destination table and checks the length of the schema
table_id = "my_table"
table_ref = dataset_ref.table(table_id)
table = client.get_table(table_ref)
print("Table {} contains {} columns.".format(table_id, len(table.schema)))

# Configures the load job to append the data to the destination table,
# allowing field addition
job_config = bigquery.LoadJobConfig()
job_config.write_disposition = bigquery.WriteDisposition.WRITE_APPEND
job_config.schema_update_options = [
    bigquery.SchemaUpdateOption.ALLOW_FIELD_ADDITION
]
# In this example, the existing table contains only the 'full_name' column.
# 'REQUIRED' fields cannot be added to an existing schema, so the
# additional column must be 'NULLABLE'.
job_config.schema = [
    bigquery.SchemaField("full_name", "STRING", mode="REQUIRED"),
    bigquery.SchemaField("age", "INTEGER", mode="NULLABLE"),
]
job_config.source_format = bigquery.SourceFormat.CSV
job_config.skip_leading_rows = 1

with open(filepath, "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_ref.table_id
    )
)

# Checks the updated length of the schema
table = client.get_table(table)
print("Table {} now contains {} columns.".format(table_id, len(table.schema)))

Agrega columnas en un trabajo de anexo de consulta

Puedes agregar columnas a una tabla cuando le anexas los resultados de consulta.

Cuando agregas columnas con una operación de anexo a un trabajo de consulta, el esquema de los resultados de la consulta se usa para actualizar el esquema de la tabla de destino. Ten en cuenta que no puedes consultar una tabla en una ubicación y escribir los resultados en una tabla de otra ubicación.

Para agregar una columna nueva cuando anexas datos en una tabla durante un trabajo de consulta, elige una de las siguientes opciones:

bq

Usa el comando bq query para consultar tus datos y especifica la marca --destination_table para indicar qué tabla anexas.

Para especificar que anexas resultados de consulta a una tabla de destino existente, agrega la marca --append_table.

Establece la marca --schema_update_option en ALLOW_FIELD_ADDITION para indicar que los resultados de consulta que anexas contienen columnas nuevas.

Especifica la marca use_legacy_sql=false para usar la sintaxis de GoogleSQL en la consulta.

Si la tabla que anexas se encuentra en un conjunto de datos de un proyecto distinto a tu proyecto predeterminado, debes agregar el ID del proyecto al nombre del conjunto de datos en el siguiente formato: PROJECT_ID:DATASET. Ten en cuenta que la tabla que consultas y la tabla de destino deben estar en la misma ubicación.

Opcional: Proporciona la marca --location y configura el valor en tu ubicación.

bq --location=LOCATION query \
--destination_table PROJECT_ID:DATASET.TABLE \
--append_table \
--schema_update_option=ALLOW_FIELD_ADDITION \
--use_legacy_sql=false \
'QUERY'

Reemplaza lo siguiente:

  • LOCATION: El nombre de tu ubicación. La marca --location es opcional. Por ejemplo, si usas BigQuery en la región de Tokio, configura el valor de la marca como asia-northeast1. Puedes configurar un valor predeterminado para la ubicación con el archivo .bigqueryrc. Ten en cuenta que no puedes agregar resultados de consultas a una tabla en otra ubicación.
  • PROJECT_ID: el ID de tu proyecto
  • dataset: el nombre del conjunto de datos que contiene la tabla que deseas agregar.
  • TABLE: es el nombre de la tabla que crearás.
  • QUERY: Una consulta en la sintaxis de GoogleSQL.

Ejemplos:

Escribe el siguiente comando para consultar mydataset.mytable en tu proyecto predeterminado y anexar los resultados de consulta a mydataset.mytable2 (que también está en tu proyecto predeterminado).

bq query \
--destination_table mydataset.mytable2 \
--append_table \
--schema_update_option=ALLOW_FIELD_ADDITION \
--use_legacy_sql=false \
'SELECT
   column1,column2
 FROM
   mydataset.mytable'

Escribe el siguiente comando para consultar mydataset.mytable en tu proyecto predeterminado y anexar los resultados de consulta a mydataset.mytable2 en myotherproject.

bq query \
--destination_table myotherproject:mydataset.mytable2 \
--append_table \
--schema_update_option=ALLOW_FIELD_ADDITION \
--use_legacy_sql=false \
'SELECT
   column1,column2
 FROM
   mydataset.mytable'

API

Realiza una llamada al método jobs.insert. Configura un trabajo query y establece las propiedades siguientes:

  • Especifica la tabla de destino con la propiedad destinationTable.
  • Establece la disposición de escritura de la tabla de destino en WRITE_APPEND con la propiedad writeDisposition.
  • Especifica la opción de actualización del esquema con la propiedad schemaUpdateOptions.
  • Especifica la consulta de GoogleSQL mediante la propiedad query.

Go

Antes de probar este ejemplo, sigue las instrucciones de configuración para Go incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Go.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

import (
	"context"
	"fmt"

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

// createTableAndWidenQuery demonstrates how the schema of a table can be modified to add columns by appending
// query results that include the new columns.
func createTableAndWidenQuery(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()

	// First, we create a sample table.
	sampleSchema := bigquery.Schema{
		{Name: "full_name", Type: bigquery.StringFieldType, Required: true},
		{Name: "age", Type: bigquery.IntegerFieldType, Required: true},
	}
	original := &bigquery.TableMetadata{
		Schema: sampleSchema,
	}
	tableRef := client.Dataset(datasetID).Table(tableID)
	if err := tableRef.Create(ctx, original); err != nil {
		return err
	}
	// Our table has two columns.  We'll introduce a new favorite_color column via
	// a subsequent query that appends to the table.
	q := client.Query("SELECT \"Timmy\" as full_name, 85 as age, \"Blue\" as favorite_color")
	q.SchemaUpdateOptions = []string{"ALLOW_FIELD_ADDITION"}
	q.QueryConfig.Dst = client.Dataset(datasetID).Table(tableID)
	q.WriteDisposition = bigquery.WriteAppend
	q.Location = "US"
	job, err := q.Run(ctx)
	if err != nil {
		return err
	}
	_, err = job.Wait(ctx)
	if err != nil {
		return err
	}
	return nil
}

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración para Java incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Java.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.JobInfo.SchemaUpdateOption;
import com.google.cloud.bigquery.JobInfo.WriteDisposition;
import com.google.cloud.bigquery.QueryJobConfiguration;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TableResult;
import com.google.common.collect.ImmutableList;

public class RelaxTableQuery {

  public static void runRelaxTableQuery() throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "MY_PROJECT_ID";
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    relaxTableQuery(projectId, datasetName, tableName);
  }

  // To relax all columns in a destination table when you append data to it during a query job
  public static void relaxTableQuery(String projectId, String datasetName, String tableName)
      throws Exception {
    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);

      String sourceTable = "`" + projectId + "." + datasetName + "." + tableName + "`";
      String query = "SELECT word FROM " + sourceTable + " WHERE word like '%is%'";

      QueryJobConfiguration queryConfig =
          QueryJobConfiguration.newBuilder(query)
              // Use standard SQL syntax for queries.
              // See: https://cloud.google.com/bigquery/sql-reference/
              .setUseLegacySql(false)
              .setSchemaUpdateOptions(ImmutableList.of(SchemaUpdateOption.ALLOW_FIELD_RELAXATION))
              .setWriteDisposition(WriteDisposition.WRITE_APPEND)
              .setDestinationTable(tableId)
              .build();

      Job queryJob = bigquery.create(JobInfo.newBuilder(queryConfig).build());

      queryJob = queryJob.waitFor();

      // Check for errors
      if (queryJob == null) {
        throw new Exception("Job no longer exists");
      } else if (queryJob.getStatus().getError() != null) {
        // You can also look at queryJob.getStatus().getExecutionErrors() for all
        // errors, not just the latest one.
        throw new Exception(queryJob.getStatus().getError().toString());
      }

      // Get the results.
      TableResult results = queryJob.getQueryResults();

      // Print all pages of the results.
      results
          .iterateAll()
          .forEach(
              rows -> {
                rows.forEach(row -> System.out.println("row: " + row.toString()));
              });

      System.out.println("Successfully relaxed all columns in destination table during query job");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Columns not relaxed during query job \n" + e.toString());
    }
  }
}

Node.js

Antes de probar este ejemplo, sigue las instrucciones de configuración para Node.js incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Node.js.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

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

// Instantiate client
const bigquery = new BigQuery();

async function addColumnQueryAppend() {
  // Adds a new column to a BigQuery table while appending rows via a query job.

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

  // Retrieve destination table reference
  const [table] = await bigquery
    .dataset(datasetId)
    .table(tableId)
    .get();
  const destinationTableRef = table.metadata.tableReference;

  // In this example, the existing table contains only the 'name' column.
  // 'REQUIRED' fields cannot  be added to an existing schema,
  // so the additional column must be 'NULLABLE'.
  const query = `SELECT name, year
    FROM \`bigquery-public-data.usa_names.usa_1910_2013\`
    WHERE state = 'TX'
    LIMIT 10`;

  // Set load job options
  const options = {
    query: query,
    schemaUpdateOptions: ['ALLOW_FIELD_ADDITION'],
    writeDisposition: 'WRITE_APPEND',
    destinationTable: destinationTableRef,
    // Location must match that of the dataset(s) referenced in the query.
    location: 'US',
  };

  const [job] = await bigquery.createQueryJob(options);
  console.log(`Job ${job.id} started.`);

  // Wait for the query to finish
  const [rows] = await job.getQueryResults();
  console.log(`Job ${job.id} completed.`);

  // Print the results
  console.log('Rows:');
  rows.forEach(row => console.log(row));
}

Python

Antes de probar este ejemplo, sigue las instrucciones de configuración para Python incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Python.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

from google.cloud import bigquery

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

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

# Retrieves the destination table and checks the length of the schema.
table = client.get_table(table_id)  # Make an API request.
print("Table {} contains {} columns".format(table_id, len(table.schema)))

# Configures the query to append the results to a destination table,
# allowing field addition.
job_config = bigquery.QueryJobConfig(
    destination=table_id,
    schema_update_options=[bigquery.SchemaUpdateOption.ALLOW_FIELD_ADDITION],
    write_disposition=bigquery.WriteDisposition.WRITE_APPEND,
)

# Start the query, passing in the extra configuration.
query_job = client.query(
    # In this example, the existing table contains only the 'full_name' and
    # 'age' columns, while the results of this query will contain an
    # additional 'favorite_color' column.
    'SELECT "Timmy" as full_name, 85 as age, "Blue" as favorite_color;',
    job_config=job_config,
)  # Make an API request.
query_job.result()  # Wait for the job to complete.

# Checks the updated length of the schema.
table = client.get_table(table_id)  # Make an API request.
print("Table {} now contains {} columns".format(table_id, len(table.schema)))

Cambia el nombre de una columna

Para cambiar el nombre de una columna en una tabla, usa la declaración DDL ALTER TABLE RENAME COLUMN. En el siguiente ejemplo, se cambia el nombre de la columna old_name a new_name en mytable:

ALTER TABLE mydataset.mytable
  RENAME COLUMN old_name TO new_name;

Para obtener más información sobre las declaraciones ALTER TABLE RENAME COLUMN, consulta Detalles de DDL.

Cambia el tipo de datos de una columna

No se admite el cambio de tipo de datos de una columna en la consola de Google Cloud, la herramienta de línea de comandos de bq ni la API de BigQuery. Si intentas actualizar una tabla mediante la aplicación de un esquema que especifique un tipo de datos nuevo para una columna, se mostrará un error

Cambia el tipo de datos de una columna con una declaración DDL

Puedes usar GoogleSQL para realizar ciertos cambios en el tipo de datos de una columna. Para obtener más información y una lista completa de las conversiones de tipos de datos admitidas, consulta la declaración DDL ALTER COLUMN SET DATA TYPE.

En el siguiente ejemplo, se crea una tabla con una columna de tipo INT64 y, luego, se actualiza el tipo a NUMERIC:

CREATE TABLE mydataset.mytable(c1 INT64);

ALTER TABLE mydataset.mytable
ALTER COLUMN c1 SET DATA TYPE NUMERIC;

En el siguiente ejemplo, se crea una tabla con una columna anidada con dos campos y, luego, se actualiza el tipo de una de las columnas de INT a NUMERIC:

CREATE TABLE mydataset.mytable(s1 STRUCT<a INT64, b STRING>);

ALTER TABLE mydataset.mytable ALTER COLUMN s1
SET DATA TYPE STRUCT<a NUMERIC, b STRING>;

Convierte el tipo de datos de una columna

Para cambiar el tipo de datos de una columna a un tipo convertible, usa una consulta en SQL para elegir los datos de la tabla, convierte la columna relevante y reemplaza la tabla. No se recomienda la conversión ni el reemplazo de tablas muy grandes, ya que esto requiere un análisis completo de las tablas.

En el siguiente ejemplo, se muestra una consulta de SQL en la que se seleccionan todos los datos de column_two y column_three en mydataset.mytable y se convierte column_one de DATE a STRING. El resultado de la consulta se usa para reemplazar los datos de la tabla existente. En la tabla cuyos datos se reemplazaron, se almacena column_one como un tipo de datos STRING.

Cuando usas CAST, la consulta puede fallar si BigQuery no puede hacer la transmisión. Para obtener más detalles sobre las reglas de conversión en GoogleSQL, consulta Transmisión.

Console

  1. En la consola de Google Cloud, ve a la página de BigQuery.

    Ir a BigQuery

  2. En el Editor de consultas, escribe la siguiente consulta para elegir todos los datos de column_two y column_three en mydataset.mytable, y para convertir column_one de DATE a STRING. La consulta usa un alias para convertir column_one de modo que conserve el mismo nombre. mydataset.mytable está en tu proyecto predeterminado.

    SELECT
     column_two,
     column_three,
     CAST(column_one AS STRING) AS column_one
    FROM
     mydataset.mytable;
  3. Haz clic en Más y elige Configuración de consulta.

  4. En la sección Destino, haz lo siguiente:

    1. Seleccione Establecer una tabla de destino para los resultados de la consulta (Set a destination table for query results).

    2. En Nombre del proyecto, deja el valor establecido en tu proyecto predeterminado. Este es el proyecto que contiene mydataset.mytable.

    3. En Conjunto de datos, elige mydataset.

    4. En el campo ID de tabla, escribe mytable.

    5. En Preferencia de escritura para la tabla de destino, elige Reemplazar tabla. Con esta opción, se reemplaza mytable con los resultados de la consulta.

  5. De manera opcional, elige la ubicación de tus datos.

  6. Para actualizar la configuración, haz clic en Guardar.

  7. Haz clic en Ejecutar.

    Cuando se completa el trabajo de consulta, el tipo de datos de column_one es STRING.

bq

Escribe el comando bq query que se muestra a continuación para elegir todos los datos de column_two y column_three en mydataset.mytable, y convertir column_one de DATE a STRING. La consulta usa un alias para convertir column_one de modo que conserve el mismo nombre. mydataset.mytable está en tu proyecto predeterminado.

Los resultados de la consulta se escriben en mydataset.mytable con la marca --destination_table y la marca --replace se usa para reemplazar los datos de mytable. Especifica la marca use_legacy_sql=false para usar la sintaxis de GoogleSQL.

Opcionalmente, proporciona la marca --location y configura el valor según tu ubicación.

bq query \
    --destination_table mydataset.mytable \
    --replace \
    --use_legacy_sql=false \
'SELECT
  column_two,
  column_three,
  CAST(column_one AS STRING) AS column_one
FROM
  mydataset.mytable'

API

Para elegir todos los datos de column_two y column_three en mydataset.mytable, además de convertir column_one de DATE a STRING, haz una llamada al método jobs.insert y configura un trabajo de query. Opcionalmente, especifica tu ubicación en la propiedad location en la sección jobReference.

La consulta de SQL que se usa en el trabajo de consulta es la siguiente: SELECT column_two, column_three, CAST(column_one AS STRING) AS column_one FROM mydataset.mytable. La consulta usa un alias para convertir column_one de modo que conserve el mismo nombre.

Para reemplazar los datos de mytable por los resultados de la consulta, incluye mydataset.mytable en la propiedad configuration.query.destinationTable y especifica WRITE_TRUNCATE en la propiedad configuration.query.writeDisposition.

Cambia el modo de una columna

La única modificación que puedes hacer al modo de una columna es cambiar REQUIRED por NULLABLE. Cambiar el modo de una columna de REQUIRED a NULLABLE se denomina disminución de la rigurosidad del modo de una columna. También puedes disminuir la rigurosidad de una columna cuando cargas datos para reemplazar una tabla existente o cuando agregas datos a una tabla existente. No puedes cambiar el modo de una columna de NULLABLE a REQUIRED.

Haz que una columna sea NULLABLE en una tabla existente

Para cambiar el modo de una columna de REQUIRED a NULLABLE, elige una de las siguientes opciones:

Console

  1. Ve a la página de BigQuery.

    Ir a BigQuery

  2. En el panel Explorador, expande el proyecto y conjunto de datos y, luego, elige la tabla.

  3. En el panel de detalles, haga clic en la pestaña Esquema.

  4. Haz clic en Editar esquema. Es posible que debas desplazarte para ver este botón.

  5. En la página Current schema (Esquema actual), busca el campo que deseas cambiar.

  6. En la lista desplegable Modo, elige NULLABLE.

  7. Para actualizar la configuración, haz clic en Guardar.

SQL

Usa la declaración DDL ALTER COLUMN DROP NOT NULL. En el siguiente ejemplo, se cambia el modo de la columna mycolumn de REQUIRED a NULLABLE:

  1. En la consola de Google Cloud, ve a la página de BigQuery.

    Ir a BigQuery

  2. En el editor de consultas, escribe la siguiente sentencia:

    ALTER TABLE mydataset.mytable
    ALTER COLUMN mycolumn
    DROP NOT NULL;

  3. Haz clic en Ejecutar.

Si deseas obtener información sobre cómo ejecutar consultas, visita Ejecuta una consulta interactiva.

bq

  1. Primero, ejecuta el comando bq show con la marca --schema y escribe el esquema de tabla existente en un archivo. Si la tabla que actualizas está en un proyecto que no es tu proyecto predeterminado, agrega el ID del proyecto al nombre del conjunto de datos en el siguiente formato: PROJECT_ID:DATASET.

    bq show \
    --schema \
    --format=prettyjson \
    PROJECT_ID:DATASET.TABLE > SCHEMA_FILE

    Reemplaza lo siguiente:

    • PROJECT_ID: el ID de tu proyecto
    • DATASET: es el nombre del conjunto de datos que contiene la tabla que estás actualizando.
    • TABLE: Es el nombre de la tabla que estás actualizando.
    • SCHEMA_FILE: es el archivo de definición de esquema que se escribe en tu máquina local.

    Por ejemplo, para escribir la definición de esquema de mydataset.mytable en un archivo, escribe el siguiente comando. mydataset.mytable está en tu proyecto predeterminado.

      bq show \
      --schema \
      --format=prettyjson \
      mydataset.mytable > /tmp/myschema.json
    
  2. Abre el archivo del esquema en un editor de texto. El esquema debe verse de la manera siguiente:

    [
      {
        "mode": "REQUIRED",
        "name": "column1",
        "type": "STRING"
      },
      {
        "mode": "REQUIRED",
        "name": "column2",
        "type": "FLOAT"
      },
      {
        "mode": "REPEATED",
        "name": "column3",
        "type": "STRING"
      }
    ]
    
  3. Cambia el modo de una columna existente de REQUIRED a NULLABLE. En este ejemplo, se disminuye la rigurosidad del modo de column1.

    [
      {
        "mode": "NULLABLE",
        "name": "column1",
        "type": "STRING"
      },
      {
        "mode": "REQUIRED",
        "name": "column2",
        "type": "FLOAT"
      },
      {
        "mode": "REPEATED",
        "name": "column3",
        "type": "STRING"
      }
    ]
    

    Para obtener más información sobre cómo trabajar con archivos de esquema JSON, consulta Especifica un archivo de esquema JSON.

  4. Después de actualizar tu archivo de esquema, ejecuta el comando siguiente para actualizar el esquema de la tabla. Si la tabla que actualizas está en un proyecto que no es tu proyecto predeterminado, agrega el ID del proyecto al nombre del conjunto de datos en el siguiente formato: PROJECT_ID:DATASET.

    bq update PROJECT_ID:DATASET.TABLE SCHEMA

    Reemplaza lo siguiente:

    • PROJECT_ID: el ID de tu proyecto
    • DATASET: es el nombre del conjunto de datos que contiene la tabla que estás actualizando.
    • TABLE: Es el nombre de la tabla que estás actualizando.
    • SCHEMA: la ruta al archivo de esquema JSON en tu máquina local.

    Por ejemplo, escribe el siguiente comando para actualizar la definición de esquema de mydataset.mytable en tu proyecto predeterminado. La ruta al archivo de esquema en tu máquina local es /tmp/myschema.json.

      bq update mydataset.mytable /tmp/myschema.json
    

API

Llama a tables.patch y usa la propiedad schema para cambiar una columna REQUIRED a NULLABLE en tu definición de esquema. Debido a que, con el método tables.update se reemplaza todo el recurso de tabla, es preferible usar el método tables.patch.

Go

Antes de probar este ejemplo, sigue las instrucciones de configuración para Go incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Go.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

import (
	"context"
	"fmt"

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

// relaxTableAPI demonstrates modifying the schema of a table to remove the requirement that columns allow
// no NULL values.
func relaxTableAPI(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()

	// Setup: We first create a table with a schema that's restricts NULL values.
	sampleSchema := bigquery.Schema{
		{Name: "full_name", Type: bigquery.StringFieldType, Required: true},
		{Name: "age", Type: bigquery.IntegerFieldType, Required: true},
	}
	original := &bigquery.TableMetadata{
		Schema: sampleSchema,
	}
	if err := client.Dataset(datasetID).Table(tableID).Create(ctx, original); err != nil {
		return err
	}

	tableRef := client.Dataset(datasetID).Table(tableID)
	meta, err := tableRef.Metadata(ctx)
	if err != nil {
		return err
	}
	// Iterate through the schema to set all Required fields to false (nullable).
	var relaxed bigquery.Schema
	for _, v := range meta.Schema {
		v.Required = false
		relaxed = append(relaxed, v)
	}
	newMeta := bigquery.TableMetadataToUpdate{
		Schema: relaxed,
	}
	if _, err := tableRef.Update(ctx, newMeta, meta.ETag); err != nil {
		return err
	}
	return nil
}

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración para Java incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Java.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

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.LegacySQLTypeName;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.StandardTableDefinition;
import com.google.cloud.bigquery.Table;

public class RelaxColumnMode {

  public static void runRelaxColumnMode() {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableId = "MY_TABLE_NAME";
    relaxColumnMode(datasetName, tableId);
  }

  public static void relaxColumnMode(String datasetName, String tableId) {
    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();

      Table table = bigquery.getTable(datasetName, tableId);

      // Create new relaxed schema based on the existing table schema
      Schema relaxedSchema =
          Schema.of(
              // The only supported modification you can make to a column's mode is changing it from
              // REQUIRED to NULLABLE
              // Changing a column's mode from REQUIRED to NULLABLE is also called column relaxation
              // INFO: LegacySQLTypeName will be updated to StandardSQLTypeName in release 1.103.0
              Field.newBuilder("word", LegacySQLTypeName.STRING)
                  .setMode(Field.Mode.NULLABLE)
                  .build(),
              Field.newBuilder("word_count", LegacySQLTypeName.STRING)
                  .setMode(Field.Mode.NULLABLE)
                  .build(),
              Field.newBuilder("corpus", LegacySQLTypeName.STRING)
                  .setMode(Field.Mode.NULLABLE)
                  .build(),
              Field.newBuilder("corpus_date", LegacySQLTypeName.STRING)
                  .setMode(Field.Mode.NULLABLE)
                  .build());

      // Update the table with the new schema
      Table updatedTable =
          table.toBuilder().setDefinition(StandardTableDefinition.of(relaxedSchema)).build();
      updatedTable.update();
      System.out.println("Table schema successfully relaxed.");
    } catch (BigQueryException e) {
      System.out.println("Table schema not relaxed \n" + e.toString());
    }
  }
}

Node.js

Antes de probar este ejemplo, sigue las instrucciones de configuración para Node.js incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Node.js.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

// Import the Google Cloud client library and create a client
const {BigQuery} = require('@google-cloud/bigquery');
const bigquery = new BigQuery();

async function relaxColumn() {
  /**
   * Changes columns from required to nullable.
   * Assumes existing table with the following schema:
   * [{name: 'Name', type: 'STRING', mode: 'REQUIRED'},
   * {name: 'Age', type: 'INTEGER'},
   * {name: 'Weight', type: 'FLOAT'},
   * {name: 'IsMagic', type: 'BOOLEAN'}];
   */

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

  const newSchema = [
    {name: 'Name', type: 'STRING', mode: 'NULLABLE'},
    {name: 'Age', type: 'INTEGER'},
    {name: 'Weight', type: 'FLOAT'},
    {name: 'IsMagic', type: 'BOOLEAN'},
  ];

  // Retrieve current table metadata
  const table = bigquery.dataset(datasetId).table(tableId);
  const [metadata] = await table.getMetadata();

  // Update schema
  metadata.schema = newSchema;
  const [apiResponse] = await table.setMetadata(metadata);

  console.log(apiResponse.schema.fields);
}

Python

Antes de probar este ejemplo, sigue las instrucciones de configuración para Python incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Python.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

Reemplaza la propiedad Table.schema por una lista de objetos SchemaField con la propiedad mode establecida en 'NULLABLE'

from google.cloud import bigquery

client = bigquery.Client()

# TODO(dev): Change table_id to full name of the table you want to create.
table_id = "your-project.your_dataset.your_table"

table = client.get_table(table_id)
new_schema = []
for field in table.schema:
    if field.mode != "REQUIRED":
        new_schema.append(field)
    else:
        # SchemaField properties cannot be edited after initialization.
        # To make changes, construct new SchemaField objects.
        new_field = field.to_api_repr()
        new_field["mode"] = "NULLABLE"
        relaxed_field = bigquery.SchemaField.from_api_repr(new_field)
        new_schema.append(relaxed_field)

table.schema = new_schema
table = client.update_table(table, ["schema"])

print(f"Updated {table_id} schema: {table.schema}.")

Haz que una columna sea NULLABLE con un trabajo de carga de anexo

Puedes disminuir la rigurosidad del modo de una columna cuando anexas datos a una tabla en un trabajo de carga. Selecciona una de las siguientes opciones según el tipo de archivo:

  • Cuando se agregan datos de archivos CSV y JSON, se disminuye la rigurosidad del modo de las columnas individuales a través de la especificación de un archivo de esquema JSON.
  • Cuando se agregan datos de archivos Avro, ORC o Parquet, se disminuye la rigurosidad de las columnas a NULL en el esquema y se permite que la inferencia de esquemas detecte las columnas con rigurosidad disminuida.

Para disminuir la rigurosidad de una columna de REQUIRED a NULLABLE cuando anexas datos a una tabla durante un trabajo de carga, elige una de las siguientes opciones:

Console

No puedes disminuir la rigurosidad del modo de una columna mediante la consola de Google Cloud.

bq

Usa el comando bq load para cargar tus datos y especifica la marca --noreplace para indicar que anexas los datos a una tabla existente.

Si los datos que agregas están en formato CSV o JSON delimitado por saltos de línea, especifica las columnas con rigurosidad disminuida en un archivo de esquema JSON local o usa la marca --autodetect para usar la detección del esquema para detectar las columnas con rigurosidad disminuida en los datos de origen.

Las columnas con rigurosidad disminuida se pueden inferir de forma automática en los archivos Avro, ORC y Parquet. La disminución de la rigurosidad de columnas no se aplica a los anexos de exportación de Datastore. Las columnas en las tablas creadas mediante la carga de archivos de exportación de Datastore siempre son NULLABLE.

Establece la marca --schema_update_option en ALLOW_FIELD_RELAXATION para indicar que los datos que anexas contienen columnas con rigurosidad disminuida.

Si la tabla que anexas se encuentra en un conjunto de datos de un proyecto distinto a tu proyecto predeterminado, debes agregar el ID del proyecto al nombre del conjunto de datos en el siguiente formato: PROJECT_ID:DATASET.

Opcional: Proporciona la marca --location y configura el valor en tu ubicación.

Escribe el comando load de la siguiente manera:

bq --location=LOCATION load \
--noreplace \
--schema_update_option=ALLOW_FIELD_RELAXATION \
--source_format=FORMAT \
PROJECT_ID:DATASET.TABLE \
PATH_TO_SOURCE \
SCHEMA

Reemplaza lo siguiente:

  • LOCATION: El nombre de tu ubicación. La marca --location es opcional. Por ejemplo, si usas BigQuery en la región de Tokio, configura el valor de la marca como asia-northeast1. Puedes configurar un valor predeterminado para la ubicación con el archivo .bigqueryrc.
  • FORMAT: Es NEWLINE_DELIMITED_JSON, CSV, PARQUET, ORC, o AVRO. Los archivos DATASTORE_BACKUP no requieren disminuir la rigurosidad de las columnas. Las columnas de las tablas creadas a partir de archivos de exportación de Datastore siempre son NULLABLE.
  • PROJECT_ID: el ID de tu proyecto
  • dataset es el nombre del conjunto de datos que contiene la tabla.
  • TABLE: es el nombre de la tabla que adjuntarás.
  • PATH_TO_SOURCE: un URI de Cloud Storage completamente calificado, una lista de URI separada por comas o la ruta a un archivo de datos en tu máquina local.
  • SCHEMA: la ruta a un archivo de esquema JSON local. Esta opción se usa solo para los archivos CSV y JSON. Las columnas con rigurosidad disminuida se infieren de forma automática desde los archivos Avro.

Ejemplos:

Escribe el siguiente comando para anexar un archivo de datos de Avro local, /tmp/mydata.avro, a mydataset.mytable mediante un trabajo de carga. Debido a que las columnas con rigurosidad disminuida se pueden deducir de forma automática de los datos de Avro, no necesitas especificar un archivo de esquema. mydataset está en tu proyecto predeterminado.

bq load \
    --noreplace \
    --schema_update_option=ALLOW_FIELD_RELAXATION \
    --source_format=AVRO \
    mydataset.mytable \
    /tmp/mydata.avro

Escribe el siguiente comando para agregar datos de un archivo JSON delimitado por saltos de línea en Cloud Storage a mydataset.mytable mediante un trabajo de carga. El esquema que contiene las columnas con rigurosidad disminuida está en un archivo de esquema JSON local, /tmp/myschema.json. mydataset está en tu proyecto predeterminado.

bq load \
--noreplace \
--schema_update_option=ALLOW_FIELD_RELAXATION \
--source_format=NEWLINE_DELIMITED_JSON \
mydataset.mytable \
gs://mybucket/mydata.json \
/tmp/myschema.json

Escribe el siguiente comando para anexar datos de un archivo CSV en tu máquina local a mydataset.mytable mediante un trabajo de carga. El comando usa la detección automática de esquemas para detectar las columnas con rigurosidad disminuida en los datos de origen. mydataset se encuentra en myotherproject, no en tu proyecto predeterminado.

bq load \
--noreplace \
--schema_update_option=ALLOW_FIELD_RELAXATION \
--source_format=CSV \
--autodetect \
myotherproject:mydataset.mytable \
mydata.csv

API

Realiza una llamada al método jobs.insert. Configura un trabajo load y establece las propiedades siguientes:

  • Haz referencia a tus datos en Cloud Storage mediante la propiedad sourceUris.
  • Para especificar el formato de datos, configura la propiedad sourceFormat.
  • Especifica el esquema en la propiedad schema.
  • Especifica la opción de actualización del esquema con la propiedad schemaUpdateOptions.
  • Establece la disposición de escritura de la tabla de destino en WRITE_APPEND con la propiedad writeDisposition.

Go

Antes de probar este ejemplo, sigue las instrucciones de configuración para Go incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Go.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

import (
	"context"
	"fmt"
	"os"

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

// relaxTableImport demonstrates amending the schema of a table to relax columns from
// not allowing NULL values to allowing them.
func relaxTableImport(projectID, datasetID, tableID, filename 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()

	sampleSchema := bigquery.Schema{
		{Name: "full_name", Type: bigquery.StringFieldType, Required: true},
		{Name: "age", Type: bigquery.IntegerFieldType, Required: true},
	}
	meta := &bigquery.TableMetadata{
		Schema: sampleSchema,
	}
	tableRef := client.Dataset(datasetID).Table(tableID)
	if err := tableRef.Create(ctx, meta); err != nil {
		return err
	}
	// Now, import data from a local file, but specify relaxation of required
	// fields as a side effect while the data is appended.
	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)
	loader.SchemaUpdateOptions = []string{"ALLOW_FIELD_RELAXATION"}
	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
	}
	return nil
}

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración para Java incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Java.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.CsvOptions;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.LoadJobConfiguration;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.StandardSQLTypeName;
import com.google.cloud.bigquery.Table;
import com.google.cloud.bigquery.TableId;
import com.google.common.collect.ImmutableList;

// Sample to append relax column in a table.
public class RelaxColumnLoadAppend {

  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";
    String sourceUri = "gs://cloud-samples-data/bigquery/us-states/us-states.csv";
    relaxColumnLoadAppend(datasetName, tableName, sourceUri);
  }

  public static void relaxColumnLoadAppend(String datasetName, String tableName, String sourceUri) {
    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();

      // Retrieve destination table reference
      Table table = bigquery.getTable(TableId.of(datasetName, tableName));

      // column as a 'REQUIRED' field.
      Field name =
          Field.newBuilder("name", StandardSQLTypeName.STRING).setMode(Field.Mode.REQUIRED).build();
      Field postAbbr =
          Field.newBuilder("post_abbr", StandardSQLTypeName.STRING)
              .setMode(Field.Mode.REQUIRED)
              .build();
      Schema schema = Schema.of(name, postAbbr);

      // Skip header row in the file.
      CsvOptions csvOptions = CsvOptions.newBuilder().setSkipLeadingRows(1).build();

      // Set job options
      LoadJobConfiguration loadConfig =
          LoadJobConfiguration.newBuilder(table.getTableId(), sourceUri)
              .setSchema(schema)
              .setFormatOptions(csvOptions)
              .setSchemaUpdateOptions(
                  ImmutableList.of(JobInfo.SchemaUpdateOption.ALLOW_FIELD_RELAXATION))
              .setWriteDisposition(JobInfo.WriteDisposition.WRITE_APPEND)
              .build();

      // Create a load job and wait for it to complete.
      Job job = bigquery.create(JobInfo.of(loadConfig));
      job = job.waitFor();
      // Check the job's status for errors
      if (job.isDone() && job.getStatus().getError() == null) {
        System.out.println("Relax column append successfully loaded in a table");
      } else {
        System.out.println(
            "BigQuery was unable to load into the table due to an error:"
                + job.getStatus().getError());
      }
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Column not added during load append \n" + e.toString());
    }
  }
}

Node.js

Antes de probar este ejemplo, sigue las instrucciones de configuración para Node.js incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Node.js.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

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

// Instantiate client
const bigquery = new BigQuery();

async function relaxColumnLoadAppend() {
  // Changes required column to nullable in load append job.

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

  // In this example, the existing table contains the 'Name'
  // column as a 'REQUIRED' field.
  const schema = 'Age:INTEGER, Weight:FLOAT, IsMagic:BOOLEAN';

  // Retrieve destination table reference
  const [table] = await bigquery
    .dataset(datasetId)
    .table(tableId)
    .get();
  const destinationTableRef = table.metadata.tableReference;

  // Set load job options
  const options = {
    schema: schema,
    schemaUpdateOptions: ['ALLOW_FIELD_RELAXATION'],
    writeDisposition: 'WRITE_APPEND',
    destinationTable: destinationTableRef,
  };

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

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

Python

Antes de probar este ejemplo, sigue las instrucciones de configuración para Python incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Python.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

# from google.cloud import bigquery
# client = bigquery.Client()
# project = client.project
# dataset_ref = bigquery.DatasetReference(project, 'my_dataset')
# filepath = 'path/to/your_file.csv'

# Retrieves the destination table and checks the number of required fields
table_id = "my_table"
table_ref = dataset_ref.table(table_id)
table = client.get_table(table_ref)
original_required_fields = sum(field.mode == "REQUIRED" for field in table.schema)
# In this example, the existing table has 3 required fields.
print("{} fields in the schema are required.".format(original_required_fields))

# Configures the load job to append the data to a destination table,
# allowing field relaxation
job_config = bigquery.LoadJobConfig()
job_config.write_disposition = bigquery.WriteDisposition.WRITE_APPEND
job_config.schema_update_options = [
    bigquery.SchemaUpdateOption.ALLOW_FIELD_RELAXATION
]
# In this example, the existing table contains three required fields
# ('full_name', 'age', and 'favorite_color'), while the data to load
# contains only the first two fields.
job_config.schema = [
    bigquery.SchemaField("full_name", "STRING", mode="REQUIRED"),
    bigquery.SchemaField("age", "INTEGER", mode="REQUIRED"),
]
job_config.source_format = bigquery.SourceFormat.CSV
job_config.skip_leading_rows = 1

with open(filepath, "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_ref.table_id
    )
)

# Checks the updated number of required fields
table = client.get_table(table)
current_required_fields = sum(field.mode == "REQUIRED" for field in table.schema)
print("{} fields in the schema are now required.".format(current_required_fields))

Haz que todas las columnas sean NULLABLE con un trabajo de anexo

Puedes disminuir la rigurosidad de todas las columnas de una tabla cuando le anexas los resultados de consulta. Puedes disminuir la rigurosidad de todos los campos obligatorios en la tabla de destino si estableces la marca --schema_update_option en ALLOW_FIELD_RELAXATION. No puedes reducir la rigurosidad de columnas individuales en una tabla de destino mediante un anexo de consulta. Para disminuir la rigurosidad de las columnas individuales con un trabajo de anexo de carga, consulta Haz que una columna sea NULLABLE con un trabajo de anexo.

Para disminuir la rigurosidad de todas las columnas cuando anexas los resultados de consulta a una tabla de destino, elige una de las siguientes opciones:

Console

No puedes disminuir la rigurosidad del modo de una columna mediante la consola de Google Cloud.

bq

Usa el comando bq query para consultar tus datos y especifica la marca --destination_table para indicar qué tabla anexas.

Para especificar que anexas resultados de consulta a una tabla de destino existente, agrega la marca --append_table.

Establece la marca --schema_update_option en ALLOW_FIELD_RELAXATION para indicar que todas las columnas REQUIRED en la tabla que anexas deben cambiarse a NULLABLE.

Especifica la marca use_legacy_sql=false para usar la sintaxis de GoogleSQL en la consulta.

Si la tabla que anexas se encuentra en un conjunto de datos de un proyecto distinto a tu proyecto predeterminado, debes agregar el ID del proyecto al nombre del conjunto de datos en el siguiente formato: PROJECT_ID:DATASET.

Opcional: Proporciona la marca --location y configura el valor en tu ubicación.

bq --location=LOCATION query \
--destination_table PROJECT_ID:DATASET.TABLE \
--append_table \
--schema_update_option=ALLOW_FIELD_RELAXATION \
--use_legacy_sql=false \
'QUERY'

Reemplaza lo siguiente:

  • LOCATION: El nombre de tu ubicación. La marca --location es opcional. Por ejemplo, si usas BigQuery en la región de Tokio, configura el valor de la marca como asia-northeast1. Puedes configurar un valor predeterminado para la ubicación con el archivo .bigqueryrc.
  • PROJECT_ID: el ID de tu proyecto
  • DATASET: el nombre del conjunto de datos que contiene la tabla que deseas agregar.
  • TABLE: es el nombre de la tabla que crearás.
  • QUERY: Una consulta en la sintaxis de GoogleSQL.

Ejemplos:

Escribe el siguiente comando para consultar mydataset.mytable en tu proyecto predeterminado y anexar los resultados de consulta a mydataset.mytable2 (que también está en tu proyecto predeterminado). El comando cambia todas las columnas REQUIRED de la tabla de destino a NULLABLE.

bq query \
    --destination_table mydataset.mytable2 \
    --append_table \
    --schema_update_option=ALLOW_FIELD_RELAXATION \
    --use_legacy_sql=false \
    'SELECT
       column1,column2
     FROM
       mydataset.mytable'

Escribe el siguiente comando para consultar mydataset.mytable en tu proyecto predeterminado y anexar los resultados de consulta a mydataset.mytable2 en myotherproject. El comando cambia todas las columnas REQUIRED de la tabla de destino a NULLABLE.

bq query \
--destination_table myotherproject:mydataset.mytable2 \
--append_table \
--schema_update_option=ALLOW_FIELD_RELAXATION \
--use_legacy_sql=false \
'SELECT
   column1,column2
 FROM
   mydataset.mytable'

API

Realiza una llamada al método jobs.insert. Configura un trabajo query y establece las propiedades siguientes:

  • Especifica la tabla de destino con la propiedad destinationTable.
  • Establece la disposición de escritura de la tabla de destino en WRITE_APPEND con la propiedad writeDisposition.
  • Especifica la opción de actualización del esquema con la propiedad schemaUpdateOptions.
  • Especifica la consulta de GoogleSQL mediante la propiedad query.

Go

Antes de probar este ejemplo, sigue las instrucciones de configuración para Go incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Go.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

import (
	"context"
	"fmt"

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

// relaxTableQuery demonstrates relaxing the schema of a table by appending query results to
// enable the table to allow NULL values.
func relaxTableQuery(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()

	sampleSchema := bigquery.Schema{
		{Name: "full_name", Type: bigquery.StringFieldType, Required: true},
		{Name: "age", Type: bigquery.IntegerFieldType, Required: true},
	}
	meta := &bigquery.TableMetadata{
		Schema: sampleSchema,
	}
	tableRef := client.Dataset(datasetID).Table(tableID)
	if err := tableRef.Create(ctx, meta); err != nil {
		return err
	}
	// Now, append a query result that includes nulls, but allow the job to relax
	// all required columns.
	q := client.Query("SELECT \"Beyonce\" as full_name")
	q.QueryConfig.Dst = client.Dataset(datasetID).Table(tableID)
	q.SchemaUpdateOptions = []string{"ALLOW_FIELD_RELAXATION"}
	q.WriteDisposition = bigquery.WriteAppend
	q.Location = "US"
	job, err := q.Run(ctx)
	if err != nil {
		return err
	}
	_, err = job.Wait(ctx)
	if err != nil {
		return err
	}
	return nil
}

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración para Java incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Java.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.JobInfo.SchemaUpdateOption;
import com.google.cloud.bigquery.JobInfo.WriteDisposition;
import com.google.cloud.bigquery.QueryJobConfiguration;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TableResult;
import com.google.common.collect.ImmutableList;

public class RelaxTableQuery {

  public static void runRelaxTableQuery() throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "MY_PROJECT_ID";
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    relaxTableQuery(projectId, datasetName, tableName);
  }

  // To relax all columns in a destination table when you append data to it during a query job
  public static void relaxTableQuery(String projectId, String datasetName, String tableName)
      throws Exception {
    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);

      String sourceTable = "`" + projectId + "." + datasetName + "." + tableName + "`";
      String query = "SELECT word FROM " + sourceTable + " WHERE word like '%is%'";

      QueryJobConfiguration queryConfig =
          QueryJobConfiguration.newBuilder(query)
              // Use standard SQL syntax for queries.
              // See: https://cloud.google.com/bigquery/sql-reference/
              .setUseLegacySql(false)
              .setSchemaUpdateOptions(ImmutableList.of(SchemaUpdateOption.ALLOW_FIELD_RELAXATION))
              .setWriteDisposition(WriteDisposition.WRITE_APPEND)
              .setDestinationTable(tableId)
              .build();

      Job queryJob = bigquery.create(JobInfo.newBuilder(queryConfig).build());

      queryJob = queryJob.waitFor();

      // Check for errors
      if (queryJob == null) {
        throw new Exception("Job no longer exists");
      } else if (queryJob.getStatus().getError() != null) {
        // You can also look at queryJob.getStatus().getExecutionErrors() for all
        // errors, not just the latest one.
        throw new Exception(queryJob.getStatus().getError().toString());
      }

      // Get the results.
      TableResult results = queryJob.getQueryResults();

      // Print all pages of the results.
      results
          .iterateAll()
          .forEach(
              rows -> {
                rows.forEach(row -> System.out.println("row: " + row.toString()));
              });

      System.out.println("Successfully relaxed all columns in destination table during query job");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Columns not relaxed during query job \n" + e.toString());
    }
  }
}

Python

Antes de probar este ejemplo, sigue las instrucciones de configuración para Python incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Python.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

from google.cloud import bigquery

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

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

# Retrieves the destination table and checks the number of required fields.
table = client.get_table(table_id)  # Make an API request.
original_required_fields = sum(field.mode == "REQUIRED" for field in table.schema)

# In this example, the existing table has 2 required fields.
print("{} fields in the schema are required.".format(original_required_fields))

# Configures the query to append the results to a destination table,
# allowing field relaxation.
job_config = bigquery.QueryJobConfig(
    destination=table_id,
    schema_update_options=[bigquery.SchemaUpdateOption.ALLOW_FIELD_RELAXATION],
    write_disposition=bigquery.WriteDisposition.WRITE_APPEND,
)

# Start the query, passing in the extra configuration.
query_job = client.query(
    # In this example, the existing table contains 'full_name' and 'age' as
    # required columns, but the query results will omit the second column.
    'SELECT "Beyonce" as full_name;',
    job_config=job_config,
)  # Make an API request.
query_job.result()  # Wait for the job to complete.

# Checks the updated number of required fields.
table = client.get_table(table_id)  # Make an API request.
current_required_fields = sum(field.mode == "REQUIRED" for field in table.schema)
print("{} fields in the schema are now required.".format(current_required_fields))

Cambia el valor predeterminado de una columna

Para cambiar el valor predeterminado de una columna, elige una de las siguientes opciones:

Console

  1. En la consola de Google Cloud, ve a la página de BigQuery.

    Ir a BigQuery

  2. En el panel Explorador, expande el proyecto y conjunto de datos y, luego, elige la tabla.

  3. En el panel de detalles, haga clic en la pestaña Esquema.

  4. Haz clic en Editar esquema. Es posible que debas desplazarte para ver este botón.

  5. En la página Esquema actual, busca el campo de nivel superior que deseas cambiar.

  6. Escribe el valor predeterminado para ese campo.

  7. Haz clic en Guardar.

SQL

Usa la declaración DDL ALTER COLUMN SET DEFAULT.

  1. En la consola de Google Cloud, ve a la página de BigQuery.

    Ir a BigQuery

  2. En el editor de consultas, escribe la siguiente sentencia:

    ALTER TABLE mydataset.mytable
    ALTER COLUMN column_name SET DEFAULT default_expression;

  3. Haz clic en Ejecutar.

Si deseas obtener información sobre cómo ejecutar consultas, visita Ejecuta una consulta interactiva.

Borra una columna

Puedes borrar una columna de una tabla existente con la declaración DDL ALTER TABLE DROP COLUMN.

La declaración no libera de inmediato el almacenamiento asociado a la columna descartada. Para obtener más información sobre el impacto en el almacenamiento cuando descartas una columna en el almacenamiento, consulta Detalles de la declaración ALTER TABLE DROP COLUMN. Hay dos opciones para reclamar el almacenamiento de inmediato:

  • Reemplaza una tabla con una consulta SELECT * EXCEPT.
  • Exporta los datos a Cloud Storage, borra las columnas no deseadas y, luego, carga los datos en una tabla nueva con el esquema correcto.