Interroger des données Cloud Storage dans des tables externes

Ce document explique comment interroger des données stockées dans une table externe Cloud Storage.

Avant de commencer

Assurez-vous de disposer d'une table externe Cloud Storage.

Rôles requis

Pour interroger des tables externes Cloud Storage, assurez-vous de disposer des rôles suivants :

  • Lecteur de données BigQuery (roles/bigquery.dataViewer)
  • Utilisateur BigQuery (roles/bigquery.user)
  • Lecteur des objets de l'espace de stockage (roles/storage.objectViewer)

Selon vos autorisations, vous pouvez vous attribuer ces rôles ou demander à votre administrateur de vous les accorder. Pour en savoir plus sur l'attribution de rôles, consultez la page Afficher les rôles pouvant être attribués sur des ressources.

Pour afficher les autorisations BigQuery exactes requises pour interroger des tables externes, développez la section Autorisations requises :

Autorisations requises

Vous pouvez également obtenir ces autorisations avec des rôles personnalisés ou d'autres rôles prédéfinis.

Interroger des tables externes permanentes

Après avoir créé une table externe Cloud Storage, vous pouvez l'interroger à l'aide de la syntaxe GoogleSQL, comme s'il s'agissait d'une table BigQuery standard. Par exemple, SELECT field1, field2 FROM mydataset.my_cloud_storage_table;.

Interroger des tables externes temporaires

L'interrogation d'une source de données externe à l'aide d'une table temporaire est utile pour les requêtes ad hoc ponctuelles qui sont exécutées sur des données externes ou pour les processus d'extraction, de transformation et de chargement (ETL, Extract-Transform-Load).

Pour interroger une source de données externe sans créer de table permanente, vous devez fournir une définition de table pour la table temporaire, puis l'utiliser dans une commande ou un appel pour interroger la table temporaire. Vous pouvez fournir la définition de la table de l'une des manières suivantes :

Le fichier de définition de table ou le schéma fourni est utilisé pour créer la table externe temporaire, sur laquelle la requête s'exécute.

En cas d'utilisation d'une table externe temporaire, vous ne créez pas de table dans l'un de vos ensembles de données BigQuery. La table n'étant pas stockée de manière permanente dans un ensemble de données, elle ne peut pas être partagée avec d'autres utilisateurs.

Vous pouvez créer et interroger une table temporaire associée à une source de données externe à l'aide de l'outil de ligne de commande bq, de l'API ou des bibliothèques clientes.

bq

La commande bq query permet d'interroger une table temporaire associée à une source de données externe à l'aide de l'option --external_table_definition. Lorsque vous utilisez l'outil de ligne de commande bq pour interroger une table temporaire associée à une source de données externe, vous pouvez spécifier le schéma de la table à l'aide de l'une des méthodes suivantes :

(Facultatif) Spécifiez l'option --location et définissez la valeur correspondant à votre emplacement.

Pour interroger une table temporaire associée à votre source de données externe à l'aide d'un fichier de définition de table, saisissez la commande suivante :

bq --location=LOCATION query \
--external_table_definition=TABLE::DEFINITION_FILE \
'QUERY'

Remplacez les éléments suivants :

  • LOCATION : nom de votre emplacement. L'option --location est facultative ; Par exemple, si vous utilisez BigQuery dans la région de Tokyo, vous pouvez définir la valeur de cette option sur asia-northeast1. Vous pouvez définir une valeur par défaut correspondant à l'emplacement en utilisant le fichier .bigqueryrc ;
  • TABLE : nom de la table temporaire que vous créez.
  • DEFINITION_FILE : chemin d'accès au fichier de définition de table sur votre ordinateur local.
  • QUERY : requête que vous soumettez à la table temporaire.

Par exemple, la commande suivante permet de créer et d'interroger une table temporaire nommée sales à l'aide du fichier de définition de table sales_def.

bq query \
--external_table_definition=sales::sales_def \
'SELECT
  Region,
  Total_sales
FROM
  sales'

Pour interroger une table temporaire associée à votre source de données externe à l'aide d'une définition de schéma intégrée, saisissez la commande suivante :

bq --location=LOCATION query \
--external_table_definition=TABLE::SCHEMA@SOURCE_FORMAT=BUCKET_PATH \
'QUERY'

Remplacez les éléments suivants :

  • LOCATION : nom de votre emplacement. L'option --location est facultative ; Par exemple, si vous utilisez BigQuery dans la région de Tokyo, vous pouvez définir la valeur de cette option sur asia-northeast1. Vous pouvez définir une valeur par défaut correspondant à l'emplacement en utilisant le fichier .bigqueryrc ;
  • TABLE : nom de la table temporaire que vous créez.
  • SCHEMA : définition de schéma en ligne au format field:data_type,field:data_type.
  • SOURCE_FORMAT : format de la source de données externe, par exemple CSV.
  • BUCKET_PATH : chemin d'accès au bucket Cloud Storage contenant les données de la table, au format gs://bucket_name/[folder_name/]file_pattern.

    Vous pouvez sélectionner plusieurs fichiers dans le bucket en spécifiant un caractère générique astérisque (*) dans le file_pattern. Par exemple, gs://mybucket/file00*.parquet. Pour en savoir plus, consultez la section Gestion des caractères génériques dans les URI Cloud Storage.

    Vous pouvez spécifier plusieurs buckets pour l'option uris en fournissant plusieurs chemins d'accès.

    Les exemples suivants montrent des valeurs uris valides :

    • gs://bucket/path1/myfile.csv
    • gs://bucket/path1/*.parquet
    • gs://bucket/path1/file1*, gs://bucket1/path1/*

    Lorsque vous spécifiez des valeurs uris qui ciblent plusieurs fichiers, tous ces fichiers doivent partager un schéma compatible.

    Pour en savoir plus sur l'utilisation des URI Cloud Storage dans BigQuery, consultez la page Chemin d'accès aux ressources Cloud Storage.

  • QUERY : requête que vous soumettez à la table temporaire.

Par exemple, la commande suivante crée et interroge une table temporaire appelée sales qui est associée à un fichier CSV stocké dans Cloud Storage avec la définition de schéma suivante : Region:STRING,Quarter:STRING,Total_sales:INTEGER.

bq query \
--external_table_definition=sales::Region:STRING,Quarter:STRING,Total_sales:INTEGER@CSV=gs://mybucket/sales.csv \
'SELECT
  Region,
  Total_sales
FROM
  sales'

Pour interroger une table temporaire associée à votre source de données externe à l'aide d'un fichier de schéma JSON, saisissez la commande suivante :

bq --location=LOCATION query \
--external_table_definition=SCHEMA_FILE@SOURCE_FORMAT=BUCKET_PATH \
'QUERY'

Remplacez les éléments suivants :

  • LOCATION : nom de votre emplacement. L'option --location est facultative ; Par exemple, si vous utilisez BigQuery dans la région de Tokyo, vous pouvez définir la valeur de cette option sur asia-northeast1. Vous pouvez définir une valeur par défaut correspondant à l'emplacement en utilisant le fichier .bigqueryrc ;
  • SCHEMA_FILE : chemin d'accès au fichier de schéma JSON sur votre ordinateur local.
  • SOURCE_FORMAT : format de la source de données externe, par exemple CSV.
  • BUCKET_PATH : chemin d'accès au bucket Cloud Storage contenant les données de la table, au format gs://bucket_name/[folder_name/]file_pattern.

    Vous pouvez sélectionner plusieurs fichiers dans le bucket en spécifiant un caractère générique astérisque (*) dans le file_pattern. Par exemple, gs://mybucket/file00*.parquet. Pour en savoir plus, consultez la section Gestion des caractères génériques dans les URI Cloud Storage.

    Vous pouvez spécifier plusieurs buckets pour l'option uris en fournissant plusieurs chemins d'accès.

    Les exemples suivants montrent des valeurs uris valides :

    • gs://bucket/path1/myfile.csv
    • gs://bucket/path1/*.parquet
    • gs://bucket/path1/file1*, gs://bucket1/path1/*

    Lorsque vous spécifiez des valeurs uris qui ciblent plusieurs fichiers, tous ces fichiers doivent partager un schéma compatible.

    Pour en savoir plus sur l'utilisation des URI Cloud Storage dans BigQuery, consultez la page Chemin d'accès aux ressources Cloud Storage.

  • QUERY : requête que vous soumettez à la table temporaire.

Par exemple, la commande suivante crée et interroge une table temporaire appelée sales qui est associée à un fichier CSV stocké dans Cloud Storage à l'aide du fichier de schéma /tmp/sales_schema.json.

  bq query \
  --external_table_definition=sales::/tmp/sales_schema.json@CSV=gs://mybucket/sales.csv \
  'SELECT
      Region,
      Total_sales
    FROM
      sales'

API

Pour exécuter une requête à l'aide de l'API, procédez comme suit:

  1. Créez un objet Job.
  2. Renseignez la section configuration de l'objet Job avec un objet JobConfiguration.
  3. Renseignez la section query de l'objet JobConfiguration avec un objet JobConfigurationQuery.
  4. Renseignez la section tableDefinitions de l'objet JobConfigurationQuery avec un objet ExternalDataConfiguration.
  5. Appeler la méthode jobs.insert pour exécuter la requête de manière asynchrone ou la méthode jobs.query pour exécuter la requête de manière synchrone, en transmettant l'objet Job.

Java

Avant d'essayer cet exemple, suivez les instructions de configuration pour Java du guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery pour Java.

Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez la page Configurer l'authentification pour les bibliothèques clientes.

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.ExternalTableDefinition;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.QueryJobConfiguration;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.StandardSQLTypeName;
import com.google.cloud.bigquery.TableResult;

// Sample to queries an external data source using a temporary table
public class QueryExternalGCSTemp {

  public static void runQueryExternalGCSTemp() {
    // TODO(developer): Replace these variables before running the sample.
    String tableName = "MY_TABLE_NAME";
    String sourceUri = "gs://cloud-samples-data/bigquery/us-states/us-states.csv";
    Schema schema =
        Schema.of(
            Field.of("name", StandardSQLTypeName.STRING),
            Field.of("post_abbr", StandardSQLTypeName.STRING));
    String query = String.format("SELECT * FROM %s WHERE name LIKE 'W%%'", tableName);
    queryExternalGCSTemp(tableName, sourceUri, schema, query);
  }

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

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

      // Configure the external data source and query job.
      ExternalTableDefinition externalTable =
          ExternalTableDefinition.newBuilder(sourceUri, csvOptions).setSchema(schema).build();
      QueryJobConfiguration queryConfig =
          QueryJobConfiguration.newBuilder(query)
              .addTableDefinition(tableName, externalTable)
              .build();

      // Example query to find states starting with 'W'
      TableResult results = bigquery.query(queryConfig);

      results
          .iterateAll()
          .forEach(row -> row.forEach(val -> System.out.printf("%s,", val.toString())));

      System.out.println("Query on external temporary table performed successfully.");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Query not performed \n" + e.toString());
    }
  }
}

Node.js

Avant d'essayer cet exemple, suivez les instructions de configuration pour Node.js du guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery pour Node.js.

Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez la page Configurer l'authentification pour les bibliothèques clientes.

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

async function queryExternalGCSTemp() {
  // Queries an external data source using a temporary table.

  const tableId = 'us_states';

  // Configure the external data source
  const externalDataConfig = {
    sourceFormat: 'CSV',
    sourceUris: ['gs://cloud-samples-data/bigquery/us-states/us-states.csv'],
    // Optionally skip header row.
    csvOptions: {skipLeadingRows: 1},
    schema: {fields: schema},
  };

  // Example query to find states starting with 'W'
  const query = `SELECT post_abbr
  FROM \`${tableId}\`
  WHERE name LIKE 'W%'`;

  // For all options, see https://cloud.google.com/bigquery/docs/reference/v2/tables#resource
  const options = {
    query,
    tableDefinitions: {[tableId]: externalDataConfig},
  };

  // Run the query as a job
  const [job] = await bigquery.createQueryJob(options);
  console.log(`Job ${job.id} started.`);

  // Wait for the query to finish
  const [rows] = await job.getQueryResults();

  // Print the results
  console.log('Rows:');
  console.log(rows);
}

Python

Avant d'essayer cet exemple, suivez les instructions de configuration pour Python du guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery pour Python.

Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez la page Configurer l'authentification pour les bibliothèques clientes.

from google.cloud import bigquery

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

# Configure the external data source and query job.
external_config = bigquery.ExternalConfig("CSV")
external_config.source_uris = [
    "gs://cloud-samples-data/bigquery/us-states/us-states.csv"
]
external_config.schema = [
    bigquery.SchemaField("name", "STRING"),
    bigquery.SchemaField("post_abbr", "STRING"),
]
external_config.options.skip_leading_rows = 1
table_id = "us_states"
job_config = bigquery.QueryJobConfig(table_definitions={table_id: external_config})

# Example query to find states starting with 'W'.
sql = 'SELECT * FROM `{}` WHERE name LIKE "W%"'.format(table_id)

query_job = client.query(sql, job_config=job_config)  # Make an API request.

w_states = list(query_job)  # Wait for the job to complete.
print("There are {} states with names starting with W.".format(len(w_states)))

Interroger la pseudo-colonne _FILE_NAME

Les tables basées sur des sources de données externes donnent accès à une pseudo-colonne intitulée _FILE_NAME. Cette colonne contient le chemin d'accès complet du fichier auquel appartient la ligne. Elle n'est disponible que pour les tables qui font référence à des données externes stockées dans Cloud Storage, Google Drive, Amazon S3 et Azure Blob Storage.

Le nom de colonne _FILE_NAME est réservé. Vous ne pouvez donc pas créer de colonne portant ce nom dans vos tables. Pour sélectionner la valeur de _FILE_NAME, vous devez utiliser un alias. Par exemple, la requête suivante sélectionne _FILE_NAME en attribuant l'alias fn à la pseudo-colonne.

  bq query \
  --project_id=PROJECT_ID \
  --use_legacy_sql=false \
  'SELECT
     name,
     _FILE_NAME AS fn
   FROM
     `DATASET.TABLE_NAME`
   WHERE
     name contains "Alex"' 

Remplacez les éléments suivants :

  • PROJECT_ID correspond à un ID de projet valide (cette option n'est pas obligatoire si vous utilisez Cloud Shell ou si vous définissez un projet par défaut dans la Google Cloud CLI).
  • DATASET correspond au nom de l'ensemble de données où est stockée la table externe permanente.
  • TABLE_NAME est le nom de la table externe permanente.

Lorsque la requête comporte un prédicat de filtre sur la pseudo-colonne _FILE_NAME, BigQuery tente d'ignorer les fichiers qui ne correspondent pas au filtre. Des recommandations similaires pour interroger des tables partitionnées par date d'ingestion à l'aide de pseudo-colonnes s'appliquent lors de la construction de prédicats de requête avec la pseudo-colonne _FILE_NAME.

Étape suivante