Carga datos de Parquet desde Cloud Storage

En esta página, se proporciona una descripción general de la carga de datos de Parquet desde Cloud Storage hacia BigQuery.

Parquet es un formato de datos orientado a columnas de código abierto muy usado en el ecosistema de Apache Hadoop.

Cuando cargas datos de Parquet desde Cloud Storage, puedes hacerlo en una tabla o partición nueva, o bien puedes agregar o reemplazar una tabla o partición existente. Cuando los datos se cargan en BigQuery, se convierten en formato de columnas para Capacitor (formato de almacenamiento de BigQuery).

Cuando cargas datos de Cloud Storage en una tabla de BigQuery, el conjunto de datos que contiene la tabla debe estar en la misma ubicación regional o multirregional que el depósito de Cloud Storage.

Para obtener más información sobre cómo cargar datos Parquet desde un archivo local, consulta Carga datos desde una fuente de datos local.

Esquemas de Parquet

Cuando cargas archivos de Parquet en BigQuery, el esquema de la tabla se recupera automáticamente de los datos de origen de descripción automática. Cuando BigQuery recupera el esquema de los datos de origen, se usa el último archivo en orden alfabético.

Por ejemplo, tienes los siguientes archivos de Parquet en Cloud Storage:

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

Cuando se ejecuta este comando en la herramienta de línea de comandos de bq, se cargan todos los archivos (como una lista separada por comas) y el esquema se deriva de mybucket/01/b.parquet:

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

Cuando cargas varios archivos de Parquet con diferentes esquemas, las columnas idénticas especificadas en múltiples esquemas deben tener el mismo modo en cada definición de esquema.

Cuando BigQuery detecta el esquema, algunos tipos de datos de Parquet se convierten en tipos de datos de BigQuery para que sean compatibles con la sintaxis de BigQuery SQL. Para obtener más información, consulta Conversiones de Parquet.

Compresión de Parquet

BigQuery admite los siguientes códecs de compresión para bloques de datos en archivos de Parquet:

  • Snappy
  • GZip
  • LZO_1C and LZO_1X

Permisos necesarios

Cuando cargas datos en BigQuery, necesitas permisos para ejecutar un trabajo de carga y permisos que te habiliten a cargar datos en tablas y particiones nuevas o existentes de BigQuery. Si cargas datos desde Cloud Storage, también necesitas permisos para acceder al depósito que contiene tus datos.

Permisos de BigQuery

Para cargar datos en BigQuery, se requieren, como mínimo, los siguientes permisos. Estos permisos son necesarios si los datos se cargan en una tabla o partición nueva, o si se agrega o reemplaza una tabla o partición.

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

En las siguientes funciones predefinidas de IAM, se incluyen los permisos bigquery.tables.create y bigquery.tables.updateData:

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

En las siguientes funciones predefinidas de IAM, se incluyen los permisos bigquery.jobs.create:

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

Además, si un usuario tiene permisos bigquery.datasets.create, se le otorga el acceso bigquery.dataOwner cuando crea un conjunto de datos. El acceso bigquery.dataOwner permite que el usuario cree y actualice tablas en el conjunto de datos mediante un trabajo de carga.

Para obtener más información sobre las funciones y los permisos de IAM en BigQuery, consulta Control de acceso.

Permisos de Cloud Storage

Para cargar datos desde un depósito de Cloud Storage, debes tener permisos storage.objects.get. Si usas un comodín de URI, también debes tener permisos storage.objects.list.

Se puede otorgar la función predefinida de IAM storage.objectViewer para proporcionar los permisos storage.objects.get y storage.objects.list.

Carga datos Parquet en una tabla nueva

Puedes cargar datos de Parquet en una tabla nueva mediante una de las siguientes opciones:

  • Cloud Console o la IU web clásicas
  • El comando bq load de la herramienta de línea de comandos de bq
  • El método de API jobs.insert y la configuración de un trabajo load
  • Las bibliotecas cliente

Para cargar datos de Parquet desde Cloud Storage en una tabla nueva de BigQuery, realiza los siguientes pasos:

Console

  1. Abre la IU web de BigQuery en Cloud Console.
    Ir a Cloud Console

  2. En el panel de navegación, en la sección Recursos, expande tu proyecto de Google Cloud y selecciona un conjunto de datos.

  3. En el lado derecho de la ventana, en el panel de detalles, haz clic en Crear tabla (Create table). El proceso de carga de datos es el mismo que el proceso para crear una tabla vacía.

    Crear tabla.

  4. En la página Crear tabla, en la sección Fuente haz lo siguiente:

    • En Crear tabla desde (Create table from), selecciona Cloud Storage.

    • En el campo de origen, busca o ingresa el URI de Cloud Storage. Ten en cuenta que no puedes incluir varios URI en Cloud Console, pero se admiten comodines. El depósito de Cloud Storage debe estar en la misma ubicación que el conjunto de datos que contiene la tabla que quieres crear.

      Seleccionar archivo.

    • En Formato de archivo (File format), selecciona Parquet.

  5. En la página Crear tabla, en la sección Destino (Destination), sigue estos pasos:

    • En Nombre del conjunto de datos (Dataset name), selecciona el conjunto de datos que corresponda.

      Ver conjunto de datos.

    • Verifica que Tipo de tabla (Table type) esté configurado como Tabla nativa (Native table).

    • En el campo Nombre de la tabla (Table name), ingresa el nombre de la tabla que quieres crear en BigQuery.

  6. En la sección Esquema no es necesaria ninguna acción. El esquema se describe en sí en archivos de Parquet.

  7. Para particionar la tabla, elige las opciones en la Configuración de partición y agrupamiento en clústeres (opcional):

    • Para crear una tabla particionada, haz clic en Sin particionar (No partitioning), selecciona Particionar por campo (Partition by field) y elige una columna DATE o TIMESTAMP. Esta opción no estará disponible si el esquema no incluye una columna DATE o TIMESTAMP.
    • Para crear una tabla particionada por tiempo de transferencia, haz clic en Sin particionar (No partitioning) y selecciona Particionar por tiempo de transferencia (Partition by ingestion time).
  8. Para el Filtro de partición, haz clic en la casilla Exigir filtro de partición a fin de solicitar a los usuarios que incluyan una cláusula WHERE que especifique las particiones que deben consultarse (opcional). Exigir un filtro de partición puede reducir los costos y mejorar el rendimiento. Para obtener más información, lee Consulta tablas particionadas. Esta opción no está disponible si se selecciona Sin particionar (No partitioning).

  9. Para agrupar en clústeres la tabla, en la casilla Orden de agrupamiento en clústeres, ingresa entre uno y cuatro nombres de campo (opcional).

  10. Haz clic en Opciones avanzadas (opcional).

    • En Preferencia de escritura (Write preference), deja seleccionado Escribir si está vacía (Write if empty). Esta opción crea una tabla nueva y carga los datos en ella.
    • En Cantidad de errores permitidos: (Number of errors allowed), acepta el valor predeterminado de 0 o ingresa la cantidad máxima de filas con errores que pueden ignorarse. Si la cantidad de filas con errores excede este valor, el trabajo generará un mensaje invalid y fallará.
    • En Valores desconocidos (Unknown values), desmarca la opción Ignorar valores desconocidos (Ignore unknown values). Esta opción se aplica solo a los archivos CSV y JSON.
    • En Encriptación, haz clic en Clave administrada por el cliente para usar una clave de Cloud Key Management Service. Si dejas establecida la configuración Clave administrada por Google (Google-managed key), BigQuery encripta los datos en reposo.
  11. Haz clic en Crear tabla (Create table).

IU clásica

  1. Ve a la IU web de BigQuery.
    Ir a la IU web de BigQuery

  2. En el panel de navegación, coloca el cursor sobre un conjunto de datos, haz clic en el ícono de flecha hacia abajo Ícono de flecha hacia abajo. y en Crear tabla nueva. El proceso de carga de datos es el mismo que el proceso para crear una tabla vacía.

  3. En la sección Datos de origen (Source Data) de la página Crear tabla (Create Table), sigue estos pasos:

    • Haz clic en Crear desde el origen (Create from source).
    • En Ubicación (Location), selecciona Cloud Storage y, en el campo de origen, ingresa el URI de Cloud Storage. Ten en cuenta que no puedes incluir varios URI en la IU web de BigQuery, pero sí se admiten comodines. El depósito de Cloud Storage debe estar en la misma ubicación que el conjunto de datos que contiene la tabla que quieres crear.
    • En Formato de archivo (File format), selecciona Parquet.
  4. En la sección Tabla de destino, sigue estos pasos:

    • En Nombre de tabla (Table name), selecciona el conjunto de datos que corresponda y, en el campo de nombre de tabla, ingresa el nombre de la tabla que quieres crear en BigQuery.
    • Verifica que Tipo de tabla (Table type) esté establecido en Tabla nativa (Native table).
  5. En la sección Esquema no es necesaria ninguna acción. El esquema se describe en sí en archivos de Parquet.

  6. En la sección Opciones, realiza los siguientes pasos (opcional):

    • En Cantidad de errores permitidos: (Number of errors allowed), acepta el valor predeterminado de 0 o ingresa la cantidad máxima de filas con errores que pueden ignorarse. Si la cantidad de filas con errores excede este valor, el trabajo generará un mensaje invalid y fallará.
    • En Preferencia de escritura (Write preference), deja seleccionado Escribir si está vacía (Write if empty). Esta opción crea una tabla nueva y carga los datos en ella.
    • Para particionar la tabla, realiza las siguientes acciones:
      • Para Tipo de partición (Partitioning Type), haz clic en Ninguna (None) y elige Día (Day).
      • En Campo de partición (Partitioning Field), haz lo siguiente:
      • Para crear una tabla particionada, elige una columna DATE o TIMESTAMP. Esta opción no estará disponible si el esquema no incluye una columna DATE o TIMESTAMP.
      • Para crear una tabla particionada por tiempo de transferencia, deja el valor predeterminado: _PARTITIONTIME.
      • Haz clic en la casilla Exigir filtro de partición para solicitar a los usuarios que incluyan una cláusula WHERE que especifique las particiones que desean consultar. Exigir un filtro de partición puede reducir los costos y mejorar el rendimiento. Para obtener más información, lee Consulta tablas particionadas. Esta opción no estará disponible si el Tipo de partición (Partitioning type) está configurado como Ninguna (None).
    • Para agrupar en clústeres la tabla, en la casilla Campos de agrupamiento en clústeres (Clustering fields), ingresa entre uno y cuatro nombres de campo.
    • En Encriptación de destino, elige Encriptación administrada por el cliente para encriptar la tabla con una clave de Cloud Key Management Service. Si dejas la configuración Default, BigQuery encripta los datos en reposo con una clave administrada por Google.
  7. Haz clic en Crear tabla (Create Table).

bq

Usa el comando bq load, especifica PARQUET con la marca --source_format y, además, incluye un URI de Cloud Storage. Puedes incluir un URI único, una lista de URI separados por comas o un URI que contenga un comodín.

Proporciona la marca --location y establece el valor de tu ubicación (opcional).

Las siguientes son otras marcas opcionales:

  • --max_bad_records: Un número entero que especifica la cantidad máxima de registros incorrectos permitidos antes de que falle todo el trabajo. El valor predeterminado es 0. Como máximo, se muestran cinco errores de cualquier tipo, sin importar el valor --max_bad_records.
  • --time_partitioning_type: Habilita las particiones basadas en el tiempo en una tabla y establece el tipo de partición. Por el momento el único valor posible es DAY, que genera una partición por día. Esta marca es opcional cuando se crea una tabla particionada en una columna DATE o TIMESTAMP.
  • --time_partitioning_expiration: Un número entero que especifica (en segundos) cuándo se debe borrar una partición basada en el tiempo. La hora de vencimiento se evalúa según la suma de la fecha de la partición en formato UTC más el valor del número entero.
  • --time_partitioning_field: La columna DATE o TIMESTAMP que se usa para crear una tabla particionada. Si la partición basada en el tiempo se habilita sin este valor, se creará una tabla particionada por tiempo de transferencia.
  • --require_partition_filter: Cuando se habilita esta opción, se solicita a los usuarios que incluyan una cláusula WHERE que especifique las particiones que se desean consultar. Exigir un filtro de partición puede reducir los costos y mejorar el rendimiento. Para obtener más información, lee Consulta tablas particionadas.
  • --clustering_fields: Es una lista separada por comas de hasta cuatro nombres de columna que se usa para crear una tabla agrupada en clústeres.
  • --destination_kms_key: Es la clave de Cloud KMS para la encriptación de los datos de la tabla.

    Para obtener más información sobre las tablas particionadas, consulta los siguientes artículos:

    Para obtener más información sobre las tablas agrupadas en clústeres, consulta el siguiente artículo:

    Para obtener más información sobre la encriptación de tablas, consulta el siguiente artículo:

Para cargar datos de Parquet en BigQuery, ingresa el siguiente comando:

bq --location=LOCATION load \
--source_format=FORMAT \
DATASET.TABLE \
PATH_TO_SOURCE

Reemplaza lo siguiente:

  • LOCATION: Es tu ubicación. La marca --location es opcional. Por ejemplo, si usas BigQuery en la región de Tokio, puedes configurar el valor de la marca como asia-northeast1. Puedes configurar un valor predeterminado para la ubicación mediante el archivo .bigqueryrc.
  • FORMAT: PARQUET.
  • DATASET: Es un conjunto de datos existente.
  • TABLE: Es el nombre de la tabla en la que se están cargando los datos.
  • PATH_TO_SOURCE: Es un URI de Cloud Storage completamente calificado o una lista de URI separados por comas. También se admiten comodines.

Ejemplos:

Con el siguiente comando, se cargan datos de gs://mybucket/mydata.parquet en una tabla llamada mytable en mydataset.

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

Con el siguiente comando, se cargan datos de gs://mybucket/mydata.parquet en una tabla particionada por tiempo de transferencia llamada mytable en mydataset.

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

Con el siguiente comando, se cargan datos de gs://mybucket/mydata.parquet en una tabla particionada llamada mytable en mydataset. La tabla está particionada en la columna mytimestamp.

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

Con el siguiente comando, se cargan datos de varios archivos de gs://mybucket/ en una tabla llamada mytable en mydataset. El URI de Cloud Storage usa un comodín.

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

Con el siguiente comando, se cargan datos de varios archivos de gs://mybucket/ en una tabla llamada mytable en mydataset. El comando incluye una lista separada por comas de URI de Cloud Storage con comodines.

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

API

  1. Crea un trabajo load que haga referencia a los datos de origen almacenados en Cloud Storage.

  2. Especifica tu ubicación en la propiedad location de la sección jobReference del recurso de trabajo (opcional).

  3. La propiedad source URIs debe estar completamente calificada en el formato gs://BUCKET/OBJECT. Cada URI puede contener un carácter comodín “*”.

  4. Configura la propiedad sourceFormat como PARQUET para especificar el formato de datos de Parquet.

  5. Para verificar el estado del trabajo, llama a jobs.get(JOB_ID*) y reemplaza JOB_ID con el ID del trabajo que muestra la solicitud inicial.

    • Si se muestra status.state = DONE, el trabajo se completó de forma correcta.
    • Si la propiedad status.errorResult está presente, la solicitud falló y ese objeto incluye información que describe lo que salió mal. Cuando una solicitud falla, no se crea ninguna tabla ni se cargan datos.
    • Si status.errorResult está ausente, el trabajo se completó con éxito, aunque puede haber algunos errores recuperables, como problemas cuando se importan algunas filas. Se enumeran los errores recuperables en la propiedad status.errors del objeto de trabajo que se muestra.

Notas de API:

  • Los trabajos de carga son atómicos y coherentes: si uno falla, ninguno de los datos estará disponible, y, si uno se realiza con éxito, todos los datos estarán disponibles.

  • Como práctica recomendada, genera un ID único y pásalo como jobReference.jobId cuando llames a jobs.insert para crear un trabajo de carga. Este enfoque es más resistente al fallo de la red porque el cliente puede sondear o reintentar con el ID de trabajo conocido.

  • Llamar a jobs.insert en un ID de trabajo determinado es idempotente. Puedes intentar tantas veces como desees en el mismo ID de trabajo y, a lo sumo, una de esas operaciones tendrá éxito.

Go

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

import (
	"context"
	"fmt"

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

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

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

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

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

Java

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

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

public class LoadParquet {

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

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

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

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

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

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

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

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

Node.js

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

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

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

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

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

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

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

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

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

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

PHP

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

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

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

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

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

Python

Antes de probar esta muestra, 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. Si deseas obtener más información, consulta la documentación de referencia de la API de BigQuery para Python.

Usa el método Client.load_table_from_uri() para iniciar un trabajo de carga desde Cloud Storage. Para usar Parquet, configura la propiedad LoadJobConfig.source_format como la constante PARQUET de SourceFormat y pasa el archivo de configuración del trabajo como el argumento job_config al método load_table_from_uri().

from google.cloud import bigquery

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

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

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

load_job = client.load_table_from_uri(
    uri, table_id, job_config=job_config
)  # Make an API request.

load_job.result()  # Waits for the job to complete.

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

Agrega o reemplaza una tabla con datos de Parquet

Puedes cargar datos adicionales en una tabla desde los archivos de origen o cuando agregas los resultados de la consulta.

En la consola y en la IU web clásica de BigQuery, usa la opción de Preferencia de escritura (Write preference) para especificar qué acción tomar cuando cargues datos desde un archivo de origen o desde un resultado de consulta.

Cuando cargas datos adicionales en una tabla, tienes las siguientes opciones:

Opción de Console Opción de IU web clásica Marca de línea de comandos Propiedad de la API de BigQuery Descripción
Escribir si está vacía (Write if empty) Escribir si está vacía (Write if empty) Ninguna WRITE_EMPTY Solo escribe los datos si la tabla está vacía.
Agregar a la tabla Agregar a la tabla --noreplace o --replace=false; si no se especifica --[no]replace, la opción predeterminada es agregar WRITE_APPEND Agrega los datos al final de la tabla (predeterminado).
Reemplaza una tabla Reemplaza una tabla --replace o --replace=true WRITE_TRUNCATE Borra todos los datos existentes de una tabla antes de escribir los datos nuevos.

Si cargas datos en una tabla existente, el trabajo de carga puede agregar los datos o reemplazar la tabla.

Puedes agregar o reemplazar una tabla con una de las siguientes opciones:

  • Cloud Console o la IU web clásica
  • El comando bq load de la herramienta de línea de comandos de bq
  • El método de API jobs.insert y la configuración de un trabajo load
  • Las bibliotecas cliente

Para agregar o sobrescribir una tabla con datos de Parquet, realiza los siguientes pasos:

Console

  1. Abre la IU web de BigQuery en Cloud Console.
    Ir a Cloud Console

  2. En el panel de navegación, en la sección Recursos, expande tu proyecto de Cloud y selecciona un conjunto de datos.

  3. En el panel de detalles, haz clic en Crear tabla (Create table). El proceso para agregar y reemplazar datos en un trabajo de carga es el mismo que el de crear una tabla en un trabajo de carga.

    Crear tabla.

  4. En la página Crear tabla, en la sección Fuente haz lo siguiente:

    • En Crear tabla desde (Create table from), selecciona Cloud Storage.

    • En el campo de origen, busca o ingresa el URI de Cloud Storage. Ten en cuenta que no puedes incluir varios URI en la IU web de BigQuery, pero sí se admiten comodines. El depósito de Cloud Storage debe encontrarse en la misma ubicación que el conjunto de datos que contiene la tabla que agregas o reemplazas.

      Seleccionar archivo.

    • En Formato de archivo (File format), selecciona Parquet.

  5. En la página Crear tabla, en la sección Destino (Destination), sigue estos pasos:

    • En Nombre del conjunto de datos (Dataset name), selecciona el conjunto de datos que corresponda.

      Seleccionar conjunto de datos.

    • En el campo Nombre de la tabla, ingresa el nombre de la tabla que quieres agregar o reemplazar en BigQuery.

    • Verifica que Tipo de tabla (Table type) esté establecido en Tabla nativa (Native table).

  6. En la sección Esquema no es necesaria ninguna acción. El esquema se describe en sí en archivos de Parquet.

  7. En Configuración de partición y agrupamiento en clústeres (Partition and cluster settings), deja los valores predeterminados. No puedes agregar datos a una tabla ni reemplazarla para convertirla en una tabla particionada o agrupada en clústeres; Cloud Console no admite agregar datos a tablas particionadas o agrupadas en clústeres ni reemplazarlas en un trabajo de carga.

  8. Haz clic en Opciones avanzadas (Advanced options).

    • En Preferencia de escritura (Write preference), elige Agregar a la tabla (Append to table) o Reemplazar tabla (Overwrite table).
    • En Cantidad de errores permitidos: (Number of errors allowed), acepta el valor predeterminado de 0 o ingresa la cantidad máxima de filas con errores que pueden ignorarse. Si la cantidad de filas con errores excede este valor, el trabajo generará un mensaje invalid y fallará.
    • En Valores desconocidos (Unknown values), desmarca la opción Ignorar valores desconocidos (Ignore unknown values). Esta opción se aplica solo a los archivos CSV y JSON.
    • En Encriptación, haz clic en Clave administrada por el cliente para usar una clave de Cloud Key Management Service. Si dejas establecida la configuración Clave administrada por Google, BigQuery encripta los datos en reposo.

      Reemplazar tabla.

  9. Haz clic en Crear tabla.

IU clásica

  1. Ve a la IU web de BigQuery.
    Ir a la IU web de BigQuery

  2. En el panel de navegación, coloca el cursor sobre un conjunto de datos, haz clic en el ícono de flecha hacia abajo Ícono de flecha hacia abajo. y, luego, en Crear tabla nueva. El proceso para agregar y reemplazar datos en un trabajo de carga es el mismo que el de crear una tabla en un trabajo de carga.

  3. En la sección Datos de origen (Source Data) de la página Crear tabla (Create Table), sigue estos pasos:

    • En Ubicación (Location), selecciona Cloud Storage y, en el campo de origen, ingresa el URI de Cloud Storage. Ten en cuenta que no puedes incluir varios URI en la IU, pero sí se admiten comodines. El depósito de Cloud Storage debe encontrarse en la misma ubicación que el conjunto de datos que contiene la tabla que agregas o reemplazas.
    • En Formato de archivo (File format), selecciona Parquet.
  4. En la página Crear tabla, en la sección Tabla de destino, realiza los siguientes pasos:

    • En Nombre de la tabla (Table name), selecciona el conjunto de datos que corresponda y, en el campo de nombre de la tabla, ingresa el nombre de la tabla a la que quieres agregarle datos o que quieres reemplazar.
    • Verifica que Tipo de tabla (Table type) esté establecido en Tabla nativa (Native table).
  5. En la sección Esquema no es necesaria ninguna acción. La información del esquema se describe en sí en archivos de Parquet.

  6. En la sección Opciones (Options), sigue estos pasos:

    • En Cantidad de errores permitidos: (Number of errors allowed), acepta el valor predeterminado de 0 o ingresa la cantidad máxima de filas con errores que pueden ignorarse. Si la cantidad de filas con errores excede este valor, el trabajo generará un mensaje invalid y fallará.
    • En Preferencia de escritura (Write preference), elige Agregar a la tabla (Append to table) o Reemplazar tabla (Overwrite table).
    • Deja los valores predeterminados en Tipo de partición (Partitioning Type), Campo de partición (Partitioning Field), Exigir filtro de partición (Require partition filter) y Campos de agrupamiento en clústeres (Clustering Fields). No puedes agregar datos a una tabla ni reemplazarla para convertirla en una tabla particionada o agrupada en clústeres; la IU web no admite agregar datos a tablas particionadas o agrupadas en clústeres ni reemplazarlas en un trabajo de carga.
    • En Encriptación de destino, elige Encriptación administrada por el cliente para encriptar la tabla con una clave de Cloud Key Management Service. Si dejas la configuración Default, BigQuery encripta los datos en reposo con una clave administrada por Google.
  7. Haz clic en Crear tabla.

bq

Ingresa el comando bq load con la marca --replace para reemplazar los datos de la tabla. Usa la marca --noreplace para agregar datos a la tabla. Si no se especifica ninguna marca, se agregan datos de manera predeterminada. Proporciona la marca --source_format y configúrala en PARQUET. Debido a que los esquemas de Parquet se recuperan de manera automática de los datos de origen autodescriptivos, no necesitas proporcionar una definición de esquema.

Proporciona la marca --location y establece el valor de tu ubicación (opcional).

Las siguientes son otras marcas opcionales:

  • --max_bad_records: Un número entero que especifica la cantidad máxima de registros incorrectos permitidos antes de que falle todo el trabajo. El valor predeterminado es 0. Como máximo, se muestran cinco errores de cualquier tipo, sin importar el valor --max_bad_records.
  • --destination_kms_key: Es la clave de Cloud KMS para la encriptación de los datos de la tabla.
bq --location=LOCATION load \
--[no]replace \
--source_format=FORMAT \
DATASET.TABLE \
PATH_TO_SOURCE

Reemplaza lo siguiente:

  • location: Es tu ubicación. La marca --location es opcional. Puedes configurar un valor predeterminado para la ubicación con el archivo .bigqueryrc.
  • format: PARQUET.
  • dataset: Es un conjunto de datos existente.
  • table: Es el nombre de la tabla en la que se están cargando los datos.
  • path_to_source: Es un URI de Cloud Storage completamente calificado o una lista de URI separados por comas. También se admiten comodines.

Ejemplos:

Con el siguiente comando, se cargan datos de gs://mybucket/mydata.parquet y se reemplazan los datos de una tabla llamada mytable en mydataset.

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

Con el siguiente comando, se cargan datos de gs://mybucket/mydata.parquet y se adjuntan datos a una tabla llamada mytable en mydataset.

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

Para obtener información sobre cómo agregar o reemplazar tablas particionadas mediante la herramienta de línea de comandos de bq, consulta Agrega y reemplaza datos de tablas particionadas.

API

  1. Crea un trabajo load que haga referencia a los datos de origen almacenados en Cloud Storage.

  2. Especifica tu ubicación en la propiedad location de la sección jobReference del recurso de trabajo (opcional).

  3. La propiedad source URIs debe estar completamente calificada en el formato gs://BUCKET/OBJECT. Puedes incluir varios URI en una lista separada por comas. Ten en cuenta que también se admiten comodines.

  4. Para especificar el formato de los datos, establece la propiedad configuration.load.sourceFormat en PARQUET.

  5. Para especificar la preferencia de escritura, establece la propiedad configuration.load.writeDisposition en WRITE_TRUNCATE o WRITE_APPEND.

Go

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

import (
	"context"
	"fmt"

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

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

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

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

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

Java

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


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

public class LoadParquetReplaceTable {

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

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

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

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

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

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

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

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

Node.js

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

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

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

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

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

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

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

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

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

PHP

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

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

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

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

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

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

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

Python

Antes de probar esta muestra, 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. Si deseas obtener más información, consulta la documentación de referencia de la API de BigQuery para Python.

Para reemplazar las filas de una tabla existente, configura la propiedad LoadJobConfig.write_disposition con la constante WRITE_TRUNCATE de WriteDisposition.

import six

from google.cloud import bigquery

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

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

job_config = bigquery.LoadJobConfig(
    schema=[
        bigquery.SchemaField("name", "STRING"),
        bigquery.SchemaField("post_abbr", "STRING"),
    ],
)

body = six.BytesIO(b"Washington,WA")
client.load_table_from_file(body, table_id, job_config=job_config).result()
previous_rows = client.get_table(table_id).num_rows
assert previous_rows > 0

job_config = bigquery.LoadJobConfig(
    write_disposition=bigquery.WriteDisposition.WRITE_TRUNCATE,
    source_format=bigquery.SourceFormat.PARQUET,
)

uri = "gs://cloud-samples-data/bigquery/us-states/us-states.parquet"
load_job = client.load_table_from_uri(
    uri, table_id, job_config=job_config
)  # Make an API request.

load_job.result()  # Waits for the job to complete.

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

Carga datos Parquet con partición de subárbol

BigQuery admite la carga de datos de Parquet particionados en Cloud Storage y propaga las columnas de partición de Hive como columnas en la tabla administrada de destino de BigQuery. Para obtener más información, consulta Carga datos con particiones externas.

Conversiones de Parquet

BigQuery convierte los tipos de datos de Parquet en los siguientes tipos de datos de BigQuery:

Tipos de conversiones

Tipo de Parquet Tipos de conversión de Parquet Tipos de datos de BigQuery
BOOLEANO NINGUNO Booleano
INT32 NINGUNO, UINT_8, UINT_16, UINT_32, INT_8, INT_16, INT_32 Número entero
INT32 DECIMAL (ver anotación DECIMAL) Numérico
INT32 FECHA Fecha
INT64 NINGUNO, UINT_64, INT_64 Número entero
INT64 DECIMAL (ver anotación DECIMAL) Numérico
INT64 TIMESTAMP_MILLIS Marca de tiempo
INT64 TIMESTAMP_MICROS Marca de tiempo
INT96 NINGUNO Marca de tiempo
FLOAT NINGUNO Punto flotante
DOBLE NINGUNO Punto flotante
BYTE_ARRAY NINGUNO Bytes
BYTE_ARRAY UTF8 String
FIXED_LEN_BYTE_ARRAY DECIMAL (ver anotación DECIMAL) Numérico
FIXED_LEN_BYTE_ARRAY NINGUNO Bytes

Otras combinaciones de tipos de Parquet y tipos convertidos no son compatibles.

Anotación decimal

Los tipos de Parquet con la anotación DECIMAL pueden tener una precisión de 38 (cantidad total de dígitos) y una escala de 9 (dígitos a la derecha del decimal). La cantidad de dígitos enteros, que es la precisión menos la escala, puede ser de 29 como máximo. Por ejemplo, DECIMAL(38, 9) es compatible porque la precisión es 38 y la escala es 9. En este ejemplo, el número de dígitos enteros es 29. DECIMAL(38, 5) no es compatible porque tiene una precisión de 38 y una escala de 5. En este ejemplo, el número de dígitos enteros es 33.

Conversiones de nombre de columna

El nombre de una columna solo debe contener letras (a-z, A-Z), números (0-9) o guiones bajos (_), y debe comenzar con una letra o guion bajo. La longitud máxima del nombre de la columna es de 128 caracteres. No se puede usar ninguno de los siguientes prefijos para el nombre de una columna:

  • _TABLE_
  • _FILE_
  • _PARTITION

No se permiten nombres de columna duplicados, incluso si tienen diferencias de mayúsculas y minúsculas. Por ejemplo, una columna llamada Column1 se considera idéntica a una columna con el nombre column1.

Por el momento, no puedes cargar archivos de Parquet que contengan columnas que tengan un punto (.) en el nombre de la columna.

Si el nombre de una columna de Parquet contiene otros caracteres (aparte de un punto), los caracteres se reemplazan por guiones bajos. Puedes agregar guiones bajos al final de los nombres de columna para evitar colisiones. Por ejemplo, si un archivo Parquet contiene 2 columnas Column1 y column1, las columnas se cargan como Column1 y column1_ respectivamente.