Charger des données dans BigQuery à partir d'une source de données locale

Pour charger des données à partir d'une source de données accessible en lecture (telle que votre ordinateur local), vous pouvez utiliser l'UI Web ou la CLI de BigQuery. Lorsque vous chargez des données à l'aide de l'UI Web ou de la CLI de BigQuery, une tâche de chargement est automatiquement créée. Vous pouvez également utiliser l'API ou les bibliothèques clientes pour créer une tâche de chargement qui va effectuer le chargement des données depuis un fichier local.

Pour consulter des tutoriels sur le chargement de fichiers CSV locaux, reportez-vous aux sections suivantes :

Limites

Le chargement de données à partir d'une source de données locale est soumis aux limites suivantes :

  • Les caractères génériques et les listes d'éléments séparés par une virgule ne sont pas compatibles avec le chargement de fichiers depuis une source de données locale. Les fichiers doivent être chargés individuellement.
  • Lorsque vous utilisez l'UI Web classique de BigQuery, les fichiers chargés à partir d'une source de données locale doivent être inférieurs ou égaux à 10 Mo et doivent contenir moins de 16 000 lignes.

Charger des données depuis une source de données locale

Pour charger des données depuis une source de données locale, procédez comme suit :

UI Web

  1. Accédez à l'UI Web de BigQuery.
    Accéder à l'UI Web de BigQuery

  2. Dans le panneau de navigation, passez la souris sur un ensemble de données. Cliquez ensuite sur la flèche vers le bas image de la flèche vers le bas, puis sur Créer une table. Le processus de chargement des données est identique au processus de création d'une table vide.

  3. Dans la section Données sources de la page Créer une table, procédez comme suit :

    • Dans le champ Zone, sélectionnez Importation de fichier. Cliquez sur Sélectionner un fichier, accédez au fichier et cliquez sur Ouvrir. Veuillez prendre en compte que les caractères génériques et les listes d'éléments séparés par une virgule ne sont pas compatibles avec les fichiers locaux.
    • Dans le champ Format de fichier, sélectionnez (CSV), JSON (délimité par un retour à la ligne), Avro, Parquet ou ORC.
  4. Dans la section Table de destination de la page Créer une table, procédez comme suit :
    • Dans le champ Nom de la table, sélectionnez l'ensemble de données approprié, puis saisissez le nom de la table que vous créez dans BigQuery.
    • Vérifiez que le paramètre Type de table est défini sur Table native.
  5. Dans la section Schéma, entrez la définition du schéma.

    • Pour les fichiers CSV et JSON, vous pouvez cocher l'option Détection automatique pour activer la détection automatique de schémas. Les informations de schéma sont extraites des fichiers Avro, Parquet et ORC à l'aide des données sources.

      lien vers la détection automatique

    • Vous pouvez également saisir les informations du schéma manuellement en utilisant les méthodes suivantes :

      • En cliquant sur Modifier sous forme de texte, puis en saisissant le schéma de la table en tant que tableau JSON :

        Ajouter un schéma en tant que tableau JSON

      • En utilisant Ajouter un champ pour saisir manuellement le schéma :

        Ajouter un schéma en utilisant l'option d'ajout de champs

  6. Sélectionnez les éléments applicables dans la section Options, puis cliquez sur Créer une table. Pour en savoir plus sur les options disponibles, consultez les sections Options CSV et Options JSON.

CLI

Utilisez la commande bq load, spécifiez la valeur pour source_format et incluez le chemin d'accès au fichier local. Saisissez le paramètre --location, puis définissez la valeur correspondant à votre zone.

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

où :

  • [LOCATION] correspond à votre zone. Le paramètre --location est facultatif si vos données se trouvent dans la zone multirégionale US ou EU. Par exemple, si vous utilisez BigQuery dans la région de Tokyo, définissez la valeur du paramètre sur asia-northeast1. Vous pouvez définir une valeur par défaut pour la zone à l'aide du fichier .bigqueryrc.
  • [FORMAT] est CSV, AVRO, PARQUET, ORC ou NEWLINE_DELIMITED_JSON.
  • [DATASET] est un ensemble de données existant.
  • [TABLE] est le nom de la table dans laquelle vous chargez des données.
  • [PATH_TO_SOURCE] est le chemin d'accès au fichier local.
  • [SCHEMA] est un schéma valide. Ce schéma peut être un fichier JSON local ou il peut être intégré à la commande. Vous pouvez également utiliser le paramètre --autodetect au lieu de fournir une définition de schéma.

En outre, vous pouvez ajouter des paramètres pour les options, qui vous permettent de contrôler la manière dont BigQuery analyse vos données. Par exemple, vous pouvez utiliser le paramètre --skip_leading_rows pour ignorer les lignes d'en-tête dans un fichier CSV. Pour en savoir plus, consultez les sections Options CSV et Options JSON.

Exemples :

  • La commande suivante permet de charger un fichier JSON délimité par un retour à la ligne (mydata.json) à partir de votre machine locale dans une table nommée mytable dans mydataset. Le schéma est défini dans un fichier de schéma local nommé myschema.json. mydataset a été créé dans la zone multirégionale US.

    bq --location=US load --source_format=NEWLINE_DELIMITED_JSON mydataset.mytable ./mydata.json ./myschema.json
    
  • La commande suivante permet de charger un fichier CSV (mydata.csv) à partir de votre machine locale dans une table nommée mytable dans mydataset. Le schéma est intégré au format [FIELD]:[DATA_TYPE], [FIELD]:[DATA_TYPE]. mydataset a été créé dans la région asia-northeast1.

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

    Remarque : Lorsque vous spécifiez le schéma sur la ligne de commande, vous ne pouvez pas inclure de type RECORD (STRUCT), de description de champ et de mode de champ. Tous les modes sont définis comme NULLABLE par défaut. Pour inclure des descriptions de champs, des modes et des types RECORD, fournissez un fichier de schéma JSON.

  • La commande suivante permet de charger un fichier CSV (mydata.csv) à partir de votre machine locale dans une table nommée mytable dans mydataset. Le schéma est défini à l'aide de la détection automatique de schéma. mydataset a été créé dans la zone multirégionale EU.

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

C#

Avant d'essayer cet exemple, suivez les instructions de configuration de C# décrites dans le Guide de démarrage rapide de BigQuery – Utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API BigQuery C#.

public void UploadJsonFromFile(string projectId, string datasetId, string tableId,
    string fileName, BigQueryClient client)
{
    using (FileStream stream = File.Open(fileName, FileMode.Open))
    {
        // This example uploads data to an existing table. If the upload will create a new table
        // or if the schema in the JSON isn't identical to the schema in the table,
        // create a schema to pass into the call instead of passing in a null value.
        BigQueryJob job = client.UploadJson(datasetId, tableId, null, stream);
        // Use the job to find out when the data has finished being inserted into the table,
        // report errors etc.

        // Wait for the job to complete.
        job.PollUntilCompleted();
    }
}

Go

Avant d'essayer cet exemple, suivez les instructions de configuration de Go décrites dans le Guide de démarrage rapide de BigQuery – Utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API BigQuery Go.

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

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

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

Java

Avant d'essayer cet exemple, suivez les instructions de configuration de Java décrites dans le Guide de démarrage rapide de BigQuery – Utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API BigQuery Java.

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

Node.js

Avant d'essayer cet exemple, suivez les instructions de configuration de Node.js dans le Guide de démarrage rapide de BigQuery – Utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API BigQuery Node.js.

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

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

// Creates a client
const bigquery = new BigQuery({
  projectId: projectId,
});

// Loads data from a local file into the table
bigquery
  .dataset(datasetId)
  .table(tableId)
  .load(filename)
  .then(results => {
    const job = results[0];

    // load() waits for the job to finish
    assert.equal(job.status.state, 'DONE');
    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;
    }
  })
  .catch(err => {
    console.error('ERROR:', err);
  });

PHP

Avant d'essayer cet exemple, suivez les instructions de configuration de PHP décrites dans le Guide de démarrage rapide de BigQuery – Utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API BigQuery 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';
// $source     = 'The path to the source file to import';

// instantiate the bigquery table service
$bigQuery = new BigQueryClient([
    'projectId' => $projectId,
]);
$dataset = $bigQuery->dataset($datasetId);
$table = $dataset->table($tableId);
// create the import job
$loadConfig = $table->load(fopen($source, 'r'));
// determine the source format from the object name
$pathInfo = pathinfo($source) + ['extension' => null];
if ('csv' === $pathInfo['extension']) {
    $loadConfig->sourceFormat('CSV');
} elseif ('json' === $pathInfo['extension']) {
    $loadConfig->sourceFormat('NEWLINE_DELIMITED_JSON');
} else {
    throw new InvalidArgumentException('Source format unknown. Must be JSON or CSV');
}
$job = $table->runJob($loadConfig);
// poll the job until it is complete
$backoff = new ExponentialBackoff(10);
$backoff->execute(function () use ($job) {
    printf('Waiting for job to complete' . PHP_EOL);
    $job->reload();
    if (!$job->isComplete()) {
        throw new Exception('Job has not yet completed', 500);
    }
});
// check if the job has errors
if (isset($job->info()['status']['errorResult'])) {
    $error = $job->info()['status']['errorResult']['message'];
    printf('Error running job: %s' . PHP_EOL, $error);
} else {
    print('Data imported successfully' . PHP_EOL);
}

Python

Avant d'essayer cet exemple, suivez les instructions de configuration de Python décrites dans le Guide de démarrage rapide de BigQuery – Utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API BigQuery Python.

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

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

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

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

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

Ruby

Avant d'essayer cet exemple, suivez les instructions de configuration de Ruby décrites dans le Guide de démarrage rapide de BigQuery – Utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API BigQuery Ruby.

# project_id      = "Your Google Cloud project ID"
# dataset_id      = "ID of the dataset containing table"
# table_id        = "ID of the table to import file data into"
# local_file_path = "Path to local file to import into BigQuery table"

require "google/cloud/bigquery"

bigquery = Google::Cloud::Bigquery.new project: project_id
dataset  = bigquery.dataset dataset_id
table    = dataset.table table_id

puts "Importing data from file: #{local_file_path}"
load_job = table.load_job local_file_path

puts "Waiting for load job to complete: #{load_job.job_id}"
load_job.wait_until_done!

puts "Data imported"

Ajouter ou écraser des données dans une table à l'aide d'un fichier local

Vous pouvez charger des données supplémentaires dans une table à partir de fichiers sources ou en ajoutant des résultats de requêtes. Si le schéma des données ne correspond pas au schéma de la table ou de la partition de destination, vous pouvez mettre à jour le schéma lorsque vous y ajoutez des données ou lorsque vous l'écrasez.

Si vous mettez à jour le schéma lors de l'ajout de données, BigQuery vous permet de réaliser les actions suivantes :

  • Ajouter des champs
  • Modifier des champs REQUIRED en NULLABLE

Si vous écrasez une table, le schéma est toujours remplacé. Les mises à jour de schéma ne sont pas limitées lorsque vous écrasez une table.

Dans l'UI Web de BigQuery, vous devez utiliser l'option Préférence d'écriture pour spécifier l'action à entreprendre lorsque vous chargez des données à partir d'un fichier source ou d'un résultat de requête. La CLI et l'API incluent les options suivantes :

Option de l'UI Web Paramètre de la CLI Propriété de l'API BigQuery Description
Écrire si la table est vide Aucun WRITE_EMPTY N'écrit les données que si la table est vide.
Ajouter à la table --noreplace ou --replace=false. Si le paramètre --[no]replace n'est pas spécifié, les données sont ajoutées par défaut. WRITE_APPEND (Par défaut) Ajoute les données à la fin de la table.
Écraser la table --replace ou --replace=true WRITE_TRUNCATE Efface toutes les données existantes d'une table avant d'écrire les nouvelles données.

Pour charger des données CSV, JSON, Avro, Parquet ou ORC depuis un fichier local et les ajouter à une table BigQuery ou les utiliser pour écraser une table BigQuery, procédez comme suit :

UI Web

  1. Dans la section Données sources de la page Créer une table, procédez comme suit :
    • Dans le champ Zone, sélectionnez Importation de fichier. Cliquez sur Sélectionner un fichier, accédez au fichier et cliquez sur Ouvrir. Veuillez prendre en compte que les caractères génériques et les listes d'éléments séparés par une virgule ne sont pas compatibles avec les fichiers locaux.
    • Dans le champ Format de fichier, sélectionnez (CSV), JSON (délimité par un retour à la ligne), Avro, Parquet ou ORC.
  2. Dans la section Table de destination de la page Créer une table, procédez comme suit :
    • Dans le champ Nom de la table, sélectionnez l'ensemble de données approprié, puis saisissez le nom de la table à laquelle vous ajoutez des données ou que vous écrasez.
    • Vérifiez que le paramètre Type de table est défini sur Table native.
  3. Dans la section Schéma, entrez la définition du schéma. Pour mettre à jour le schéma, vous pouvez ajouter de nouveaux champs ou modifier (assouplir) les champs en les faisant passer de REQUIRED à NULLABLE.

    • Pour les fichiers JSON, vous pouvez cocher l'option Détection automatique pour activer la détection automatique de schémas.

      lien vers la détection automatique

    • Vous pouvez également saisir les informations du schéma manuellement en utilisant les méthodes suivantes :

      • En cliquant sur Modifier sous forme de texte, puis en saisissant le schéma de la table en tant que tableau JSON :

        Ajouter un schéma en tant que tableau JSON

      • En utilisant Ajouter un champ pour saisir manuellement le schéma :

        Ajouter un schéma en utilisant l'option d'ajout de champs

  4. Dans la section Options, pour Préférence d'écriture, choisissez Écrire si la table est vide, Ajouter à la table ou Écraser la table.

    Ajouter un schéma en utilisant l'option d'ajout de champs

  5. Cliquez sur Créer une table.

Ligne de commande

Exécutez la commande bq load avec le paramètre --replace pour écraser la table. Incluez le paramètre --noreplace pour ajouter des données à la table. Si aucun paramètre n'est spécifié, les données sont ajoutées par défaut. Saisissez le paramètre --location, puis définissez la valeur correspondant à votre zone.

Lorsque vous ajoutez ou écrasez une table, vous pouvez utiliser le paramètre --schema_update_option pour mettre à jour le schéma de la table de destination avec le schéma des nouvelles données. Les options suivantes peuvent être utilisées avec le paramètre --schema_update_option :

  • ALLOW_FIELD_ADDITION : ajoute de nouveaux champs au schéma ; ces nouveaux champs ne peuvent pas être REQUIRED.
  • ALLOW_FIELD_RELAXATION : change les champs obligatoires en champs pouvant être vides ; répétez cette option pour spécifier une liste de valeurs.

bq --location=[LOCATION] load --[no]replace [DATASET].[TABLE] [PATH_TO_SOURCE] [SCHEMA]

où :

  • [LOCATION] correspond à votre zone. Le paramètre --location est facultatif si vos données se trouvent dans la zone multirégionale US ou EU. Par exemple, si vous utilisez BigQuery dans la région de Tokyo, définissez la valeur du paramètre sur asia-northeast1. Vous pouvez définir une valeur par défaut pour la zone à l'aide du fichier .bigqueryrc.
  • [DATASET] est un ensemble de données existant.
  • [TABLE] est le nom de la table dans laquelle vous chargez des données.
  • [PATH_TO_SOURCE] est le chemin d'accès au fichier local. Veuillez prendre en compte que les caractères génériques et les listes d'éléments séparés par une virgule ne sont pas compatibles avec les fichiers locaux.
  • [SCHEMA] est un schéma valide. Ce schéma peut être un fichier JSON local ou il peut être intégré à la commande. Vous pouvez également utiliser le paramètre --autodetect au lieu de fournir une définition de schéma.

En outre, vous pouvez ajouter des paramètres pour les options JSON et les options CSV, qui vous permettent de contrôler la manière dont BigQuery analyse vos données.

Exemples :

  • La commande suivante permet de charger les données de mydata.json en écrasant une table nommée mytable dans mydataset. Le schéma est défini à l'aide de la détection automatique de schéma. mydataset a été créé dans la zone multirégionale US.

    bq --location=US load --autodetect --replace --source_format=NEWLINE_DELIMITED_JSON mydataset.mytable ./mydata.json
    
  • La commande suivante permet de charger les données de mydata.json en ajoutant des données à une table nommée mytable dans mydataset. Le schéma est défini à l'aide d'un fichier de schéma JSON (myschema.json). mydataset a été créé dans la zone multirégionale US.

    bq --location=US load --autodetect --noreplace --source_format=NEWLINE_DELIMITED_JSON mydataset.mytable ./mydata.json ./myschema.json
    
  • La commande suivante permet de charger les données de mydata.json en ajoutant des données à une table nommée mytable dans mydataset. Un fichier de schéma JSON local nommé myschema.json est utilisé. La définition de schéma contient de nouveaux champs non présents dans la table de destination. mydataset a été créé dans la zone multirégionale EU.

    bq --location=EU load --noreplace --schema_update_option=ALLOW_FIELD_ADDITION --source_format=NEWLINE_DELIMITED_JSON mydataset.mytable ./mydata.json ./myschema.json
    
  • La commande suivante permet de charger les données de mydata.csv en ajoutant des données à une table nommée mytable dans mydataset. Un fichier de schéma JSON local nommé myschema.json est utilisé. La définition de schéma permet de changer (assouplir) deux champs REQUIRED en NULLABLE. mydataset a été créé dans la région asia-northeast1.

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

La fonctionnalité d'importation de médias permet à l'API de Google BigQuery de stocker des données dans le cloud et de les rendre disponibles sur le serveur. Vous pouvez souhaiter importer des photos, des vidéos, des fichiers PDF, des fichiers zip ou tout autre type de données.

Options d'importation

L'API de Google BigQuery vous permet d'importer certains types de données binaires ou des médias. Les caractéristiques spécifiques des données que vous pouvez importer sont spécifiées sur la page de référence pour toutes les méthodes compatibles avec l’importation de médias :

  • Taille maximale du fichier d'importation : la quantité maximale de données que vous pouvez stocker à l'aide de cette méthode.
  • Types MIME de médias acceptés : les types de données binaires que vous pouvez stocker à l'aide de cette méthode.

Vous pouvez effectuer des requêtes d'importation via l'une des méthodes exposées ci-dessous. Spécifiez la méthode que vous utilisez avec le paramètre de requête uploadType.

  • Importation en plusieurs parties : uploadType=multipart. Pour un transfert rapide de petits fichiers et métadonnées ; transfère le fichier avec les métadonnées qui le décrivent, dans une seule requête.
  • Importation avec reprise : uploadType=resumable. Pour un transfert fiable, particulièrement important avec des fichiers plus volumineux. Avec cette méthode, vous utilisez une requête de lancement de session, qui peut éventuellement inclure des métadonnées. Il s'agit d'une bonne stratégie à utiliser pour la plupart des applications, car elle fonctionne également pour des fichiers plus petits au prix d'une requête HTTP supplémentaire par importation.

Lorsque vous importez un média, vous utilisez un URI spécial. Concrètement, les méthodes compatibles avec l'importation de médias possèdent deux points de terminaison URI :

  • L'URI /upload, pour les médias. Le format du point de terminaison de l'importation correspond à l'URI de ressource standard avec un préfixe "/upload". Utilisez cet URI lors du transfert des données du média. Exemple : POST /upload/bigquery/v2/projects/<projectId>/jobs.
  • L'URI de ressource standard, pour les métadonnées. Si la ressource contient des champs de données, ces champs sont utilisés pour stocker les métadonnées décrivant le fichier importé. Vous pouvez utiliser cet URI pour créer ou mettre à jour des valeurs de métadonnées. Exemple : POST /bigquery/v2/projects/<projectId>/jobs.

Importation en plusieurs parties

Si vous souhaitez envoyer des métadonnées avec les données à importer, vous pouvez effectuer une seule requête multipart/related. Cette opération est judicieuse si les données que vous envoyez sont suffisamment petites pour pouvoir être importées intégralement en cas d'échec de connexion.

Pour utiliser l'importation en plusieurs parties, envoyez une requête POST à l'URI /upload de la méthode et ajoutez le paramètre de requête uploadType=multipart. Exemple :

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

Les en-têtes HTTP de premier niveau à utiliser lors d'une importation en plusieurs parties incluent :

  • Content-Type. Défini sur multipart/related et inclut la chaîne de délimitation que vous utilisez pour identifier les parties de la requête.
  • Content-Length. Défini sur le nombre total d'octets dans le corps de la requête. La partie de médias de la requête doit être inférieure à la taille de fichier maximale spécifiée pour cette méthode.

Le corps de la requête est formaté en tant que type de contenu multipart/related [RFC2387] et contient exactement deux parties. Les parties sont identifiées par une chaîne de délimitation et la dernière chaîne est suivie de deux traits d'union.

Chaque partie de la requête en plusieurs parties nécessite un en-tête Content-Type supplémentaire :

  1. Partie de métadonnées : doit apparaître en premier et la valeur Content-Type doit correspondre à l'un des formats de métadonnées acceptés.
  2. Partie de médias : doit apparaître en second et la valeur Content-Type doit correspondre à l'un des types MIME de médias acceptés de la méthode.

Consultez la documentation de référence sur les API pour obtenir une liste relative à chaque méthode de types MIME de médias acceptés et de limites de taille pour les fichiers importés.

Remarque : Pour ne créer ou mettre à jour que la partie de métadonnées sans importer les données associées, envoyez simplement une requête POST ou PUT au point de terminaison de ressource standard : https://www.googleapis.com/bigquery/v2/projects/<projectId>/jobs.

Exemple : Importation en plusieurs parties

L'exemple ci-dessous montre une requête d'importation en plusieurs parties pour l'API de Google BigQuery :

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

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

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

--foo_bar_baz
Content-Type: */*

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

Si la requête aboutit, le serveur affiche le code d'état HTTP 200 OK avec toutes les métadonnées :

HTTP/1.1 200
Content-Type: application/json

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

Importation avec reprise

Pour importer des fichiers de données de manière plus fiable, vous pouvez utiliser le protocole d'importation avec reprise. Ce protocole vous permet de reprendre une opération d'importation après un échec de communication ayant interrompu le flux de données. Cette opération est particulièrement utile si vous transférez des fichiers volumineux et que les risques d'interruption du réseau ou d'échec de transmission sont élevés, par exemple si l'importation est réalisée depuis une application cliente mobile. Cela peut également réduire l'utilisation de la bande passante en cas d'échec du réseau, car cela vous évite de redémarrer les importations de fichiers volumineux depuis le début.

Pour réaliser une importation avec reprise, procédez comme suit :

  1. Démarrez une session avec reprise. Effectuez une requête initiale à l'URI d'importation contenant les métadonnées, le cas échéant.
  2. Enregistrez l'URI de la session avec reprise. Enregistrez l'URI de la session affichée dans la réponse à la requête initiale. Vous l'utiliserez pour les requêtes restantes dans cette session.
  3. Importez le fichier. Envoyez le fichier de médias à l'URI de la session avec reprise.

En outre, les applications qui utilisent l'importation avec reprise doivent posséder un code pour reprendre une importation interrompue. En cas d'interruption de l'importation, déterminez la quantité de données reçue, puis reprenez l'importation à partir de ce point.

Remarque : Une URI d'importation est valable une semaine.

Étape 1 : Démarrez une session avec reprise

Pour démarrer l'importation avec reprise, envoyez une requête POST à l'URI /upload de la méthode et ajoutez le paramètre de requête uploadType=resumable. Exemple :

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

Le corps de cette requête de lancement doit être vide ou ne contenir que les métadonnées. Vous allez transférer le contenu réel du fichier que vous souhaitez importer dans les requêtes ultérieures.

Utilisez les en-têtes HTTP suivants avec la requête initiale :

  • X-Upload-Content-Type. Définissez le type MIME de média des données d'importation à transférer dans les requêtes ultérieures.
  • X-Upload-Content-Length. Définissez le nombre d'octets des données d'importation à transférer dans les requêtes ultérieures.  Si cette valeur est inconnue au moment de cette requête, vous pouvez omettre cet en-tête.
  • Si vous fournissez des métadonnées : Content-Type. Définissez cette valeur en fonction du type de données des métadonnées.
  • Content-Length. Définissez le nombre d'octets fournis dans le corps de cette requête initiale. Champ non requis si vous utilisez l'encodage de transfert fragmenté.

Consultez la documentation de référence sur les API pour obtenir une liste relative à chaque méthode de types MIME de médias acceptés et de limites de taille pour les fichiers importés.

Exemple : Requête de lancement de session avec reprise

L'exemple suivant montre comment lancer une session avec reprise pour l'API de Google BigQuery :

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

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

Remarque : Pour une requête initiale de mise à jour d'importation avec reprise sans métadonnées, ne remplissez pas le corps de la requête et définissez l'en-tête Content-Length sur 0.

La section suivante décrit comment gérer la réponse.

Étape 2 : Enregistrez l'URI de la session avec reprise

Si la requête d'ouverture de session aboutit, le serveur API répond par un code d'état HTTP 200 OK. En outre, il fournit un en-tête Location qui spécifie votre URI de session avec reprise. L'en-tête Location, illustré dans l'exemple ci-dessous, inclut une partie de paramètre de requête upload_id qui fournit l'ID d'importation unique à utiliser pour cette session.

Exemple : Réponse de lancement de session avec reprise

La réponse à la requête de l'étape 1 se présente comme suit :

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

La valeur de l'en-tête Location, comme indiqué dans l'exemple de réponse ci-dessus, correspond à l'URI de session que vous utiliserez comme point de terminaison HTTP afin d'effectuer l'importation du fichier ou interroger le statut de l'importation.

Copiez et enregistrez l'URI de la session afin de pouvoir l'utiliser pour les requêtes ultérieures.

Étape 3 : Importez le fichier

Pour importer le fichier, envoyez une requête PUT à l'URI d'importation obtenu lors de l'étape précédente. Le format de la requête d'importation se présente comme suit :

PUT session_uri

Les en-têtes HTTP à utiliser lors des requêtes d'importation de fichiers avec reprise incluent Content-Length. Définissez cette valeur sur le nombre d'octets que vous importez dans cette requête, qui correspond généralement à la taille du fichier à importer.

Exemple : Requête d'importation de fichier avec reprise

Voici une requête avec reprise permettant d'importer l'intégralité du fichier CSV, JSON, AVRO, PARQUET ou ORC de 2 000 000 octets pour l'exemple actuel :

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

bytes 0-1999999

Si la requête aboutit, le serveur répond avec un HTTP 201 Created, ainsi que toutes les métadonnées associées à cette ressource. Si la requête initiale de la session avec reprise était un PUT, la réponse positive serait 200 OK pour mettre à jour une ressource existante, avec toutes les métadonnées associées à cette ressource.

Si la requête d'importation est interrompue ou si le serveur vous envoie une réponse HTTP 503 Service Unavailable ou toute autre réponse 5xx, suivez la procédure expliquant comment reprendre une importation interrompue.  


Importer un fichier fragmenté

Les importations avec reprise vous permettent de diviser un fichier en plusieurs fragments et d'envoyer une série de requêtes afin d'importer chacun de ces fragments l'un après l'autre. Cette méthode n'est pas conseillée, car des coûts de performance sont associés aux requêtes supplémentaires, ce qui n’est généralement pas nécessaire. Toutefois, vous aurez peut-être recours à la fragmentation pour réduire la quantité de données transférées dans une requête unique. C'est utile lorsque le temps imparti à chaque requête est limité pour les requêtes individuelles, comme c'est le cas pour certaines classes de requêtes Google App Engine. Cela vous permet également de fournir des indications concernant la progression de l'importation pour les anciens navigateurs qui ne possèdent pas cette fonctionnalité par défaut.


Reprendre une importation interrompue

Si une requête d'importation se termine avant de recevoir une réponse ou si vous recevez une réponse HTTP 503 Service Unavailable du serveur, vous devez reprendre l'importation interrompue. Pour ce faire, procédez comme suit :

  1. Interroger l'état. Interrogez l'état actuel de l'importation en envoyant une requête PUT vide à l'URI d'importation. Pour cette requête, les en-têtes HTTP doivent inclure un en-tête Content-Range indiquant que la position actuelle dans le fichier est inconnue.  Par exemple, définissez la valeur Content-Range sur */2000000 si la longueur totale de votre fichier correspond à 2 000 000. Si vous ignorez la taille totale du fichier, définissez la valeur Content-Range sur */*.

    Remarque : Vous pouvez interroger l’état entre les fragments, et pas seulement si l'importation est interrompue. Cette opération est utile si vous souhaitez afficher les indications concernant la progression de l'importation pour les navigateurs anciens, par exemple.

  2. Obtenir le nombre d'octets importés. Traitez la réponse à partir de la requête d'état. Le serveur utilise l'en-tête Range dans sa réponse pour spécifier les octets reçus jusqu'à présent.  Par exemple, un en-tête Range de 0-299999 indique que les 300 000 premiers octets du fichier ont été reçus.
  3. Importer les données restantes. Enfin, maintenant que vous savez où reprendre la requête, envoyez les données restantes ou le fragment actuel. Veuillez prendre en compte que vous devez traiter les données restantes comme un fragment séparé quoiqu'il arrive. Vous devez donc envoyer l'en-tête Content-Range au moment de la reprise de l'importation.
Exemple : Reprendre une importation interrompue

1) Interroger l'état de l'importation.

La requête suivante utilise l'en-tête Content-Range pour indiquer que la position actuelle dans le fichier de 2 000 000 octets est inconnue.

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

2) Procédez à l'extraction du nombre d’octets importés jusqu'à présent à partir de la réponse.

La réponse du serveur utilise l'en-tête Range pour indiquer qu'il a reçu les 43 premiers octets du fichier jusqu'à présent. Utilisez la valeur supérieure de l'en-tête Range pour déterminer où démarrer la reprise de l'importation.

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

Remarque : Il est possible que la réponse d'état corresponde à 201 Created ou 200 OK si l'importation est terminée. Cette situation peut se produire si la connexion s'interrompt après l'importation de tous les octets, mais avant que le client ne reçoive une réponse du serveur.

3) Reprenez l'importation là où elle s'était arrêtée.

La requête suivante reprend l'importation en envoyant les octets restants du fichier, en commençant par l'octet 43.

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

bytes 43-1999999

Bonnes pratiques

En ce qui concerne l'importation de médias, il est utile de connaître certaines bonnes pratiques en matière de traitement des erreurs.

  • Reprenez ou relancez les importations qui échouent en raison d'interruptions de connexion ou d'erreurs 5xx, parmi lesquelles :
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout
  • Utilisez une stratégie d'intervalle exponentiel entre les tentatives si une erreur de serveur 5xx est affichée lors de la reprise ou de la nouvelle tentative d'importation. Ces erreurs peuvent se produire quand un serveur est surchargé. L'intervalle exponentiel entre les tentatives peut aider à résoudre ce type de problèmes lors des pics de volumes de requêtes ou de trafic réseau.
  • Les autres types de requêtes ne doivent pas être traités par un intervalle exponentiel entre les tentatives, mais vous pouvez toujours essayer d'en relancer. Lorsque vous relancez ces requêtes, limitez le nombre de tentatives. Par exemple, votre code peut établir une limite de dix tentatives ou moins avant de signaler une erreur.
  • Traitez les erreurs 404 Not Found lorsque vous effectuez des importations avec reprise en commençant l'importation complète depuis le début.

Intervalle exponentiel entre les tentatives

L'intervalle exponentiel entre les tentatives est une stratégie standard en matière de traitement d'erreurs pour les applications réseau avec lesquelles le client relance périodiquement une requête ayant échoué sur une durée de plus en plus longue. Si un volume élevé de requêtes ou un trafic réseau important provoque des erreurs sur le serveur, l'intervalle exponentiel entre les tentatives peut s'imposer comme une stratégie efficace pour gérer le traitement de ces erreurs. À l'inverse, cette stratégie n'est pas pertinente pour traiter les erreurs sans rapport avec le volume réseau ou les temps de réponse, telles que les erreurs relatives aux identifiants d'autorisation non valides ou aux fichiers introuvables.

Utilisé correctement, l'intervalle exponentiel entre les tentatives augmente l'efficacité de l'utilisation de la bande passante, réduit le nombre de requêtes requises pour obtenir une réponse positive et optimise le débit des requêtes dans des environnements concurrents.

Le flux de mise en œuvre de l'intervalle exponentiel simple entre les tentatives se présente comme suit :

  1. Envoyez une requête à l'API.
  2. Recevez une réponse HTTP 503, qui indique que vous devez relancer la requête.
  3. Attendez 1 seconde + random_number_milliseconds, puis relancez la requête.
  4. Recevez une réponse HTTP 503, qui indique que vous devez relancer la requête.
  5. Attendez 2 secondes + random_number_milliseconds, puis relancez la requête.
  6. Recevez une réponse HTTP 503, qui indique que vous devez relancer la requête.
  7. Attendez 4 secondes + random_number_milliseconds, puis relancez la requête.
  8. Recevez une réponse HTTP 503, qui indique que vous devez relancer la requête.
  9. Attendez 8 secondes + random_number_milliseconds, puis relancez la requête.
  10. Recevez une réponse HTTP 503, qui indique que vous devez relancer la requête.
  11. Attendez 16 secondes + random_number_milliseconds, puis relancez la requête.
  12. Arrêtez. Signalez ou enregistrez une erreur.

Dans le flux ci-dessus, random_number_milliseconds correspond à un nombre aléatoire de millisecondes inférieur ou égal à 1 000. Cette valeur est nécessaire, car l'introduction d'un petit délai aléatoire aide à répartir la charge de manière plus uniforme et à éviter la possibilité d'estampillage du serveur. La valeur de random_number_milliseconds doit être redéfinie après chaque temps d'attente.

Remarque : L'attente correspond toujours à (2 ^ n) + random_number_milliseconds, où n est un entier augmentant de manière monotone défini initialement sur 0. L'entier n est augmenté de 1 pour chaque itération (chaque requête).

L'algorithme est configuré pour se terminer lorsque n vaut 5. Ce plafond empêche les clients d'effectuer des relances indéfiniment, et entraîne un délai total d'environ 32 secondes avant qu'une requête ne soit considérée comme une "erreur non récupérable". Vous pouvez tout à fait définir un nombre maximal de tentatives plus élevé, surtout si une longue importation est en cours d'exécution. Veillez simplement à limiter le délai des nouvelles tentatives de manière raisonnable, par exemple à moins d'une minute.

Cette page vous a-t-elle été utile ? Évaluez-la :

Envoyer des commentaires concernant…

Besoin d'aide ? Consultez notre page d'assistance.