查詢外部資料表中的 Cloud Storage 資料

本文件說明如何查詢儲存在 Cloud Storage 外部資料表中的資料。

事前準備

確認您有 Cloud Storage 外部資料表

必要的角色

如要查詢 Cloud Storage 外部資料表,請確認您具備下列角色:

  • BigQuery 資料檢視者 (roles/bigquery.dataViewer)
  • BigQuery 使用者 (roles/bigquery.user)
  • Storage 物件檢視器 (roles/storage.objectViewer)

視您的權限而定,您可以授予自己這些角色,或請管理員授予您這些角色。如要進一步瞭解如何授予角色,請參閱「查看可針對資源授予的角色」。

如要查看查詢外部資料表所需的確切 BigQuery 權限,請展開「Required permissions」部分:

所需權限

您或許還可透過自訂角色或其他預先定義的角色取得這些權限。

查詢永久外部資料表

建立 Cloud Storage 外部資料表後,您可以使用 GoogleSQL 語法查詢資料表,就像查詢標準 BigQuery 資料表一樣。例如:SELECT field1, field2 FROM mydataset.my_cloud_storage_table;

查詢臨時外部資料表

使用臨時資料表查詢外部資料來源,對於一次性、臨時查詢外部資料,或對擷取、轉換和載入 (ETL) 處理程序而言非常有用。

如要查詢外部資料來源,但不想建立永久資料表,請為臨時資料表提供資料表定義,然後在指令或呼叫中使用該資料表定義來查詢臨時資料表。您可以透過下列任一方式提供資料表定義:

系統會使用資料表定義檔或提供的結構定義來建立臨時外部資料表,然後對臨時外部資料表執行查詢。

使用臨時外部資料表時,並不會在某個 BigQuery 資料集中建立資料表。因為資料表不會永久儲存在資料集中,所以無法與其他使用者分享。

您可以使用 bq 指令列工具、API 或用戶端程式庫,建立和查詢連結到外部資料來源的臨時資料表。

bq

您可以搭配 --external_table_definition 旗標使用 bq query 指令,查詢已連結至外部資料來源的臨時資料表。使用 bq 指令列工具查詢連結至外部資料來源的臨時資料表時,可以透過以下項目識別資料表的結構定義:

(選用) 提供 --location 旗標,並將值設為您的位置

如要使用資料表定義檔查詢連接外部資料來源的臨時資料表,請輸入下列指令。

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

更改下列內容:

  • LOCATION位置名稱。--location 是選用旗標。舉例來說,如果您在東京地區使用 BigQuery,就可以將該旗標的值設定為 asia-northeast1。您可以使用 .bigqueryrc 檔案設定位置的預設值。
  • TABLE:要建立的臨時資料表名稱。
  • DEFINITION_FILE:本機電腦上資料表定義檔的路徑。
  • QUERY:要提交至臨時資料表的查詢。

舉例來說,下列指令會使用名為 sales_def 的資料表定義檔,建立及查詢名為 sales 的臨時資料表。

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

如要使用內嵌結構定義來查詢連結至外部資料來源的臨時資料表,請輸入下列指令。

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

更改下列內容:

  • LOCATION位置名稱。--location 是選用旗標。舉例來說,如果您在東京地區使用 BigQuery,就可以將該旗標的值設定為 asia-northeast1。您可以使用 .bigqueryrc 檔案設定位置的預設值。
  • TABLE:要建立的臨時資料表名稱。
  • SCHEMA:內嵌結構定義,格式為 field:data_type,field:data_type
  • SOURCE_FORMAT:外部資料來源的格式,例如 CSV
  • BUCKET_PATH:包含資料表資料的 Cloud Storage 值區路徑,格式為 gs://bucket_name/[folder_name/]file_pattern

    您可以在 file_pattern 中指定一個星號 (*) 萬用字元,從值區中選取多個檔案。例如 gs://mybucket/file00*.parquet。詳情請參閱「Cloud Storage URI 的萬用字元支援」。

    您可以提供多個路徑,為 uris 選項指定多個值區。

    以下範例顯示有效的 uris 值:

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

    指定以多個檔案為目標的 uris 值時,所有檔案都必須共用相容的結構定義。

    如要進一步瞭解如何在 BigQuery 中使用 Cloud Storage URI,請參閱「Cloud Storage 資源路徑」。

  • QUERY:要提交至臨時資料表的查詢。

舉例來說,下列指令會使用 Region:STRING,Quarter:STRING,Total_sales:INTEGER 結構定義,建立和查詢名為 sales 的臨時資料表,且此表會連結至儲存在 Cloud Storage 中的 CSV 檔案。

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

如要使用 JSON 結構定義檔來查詢連接外部資料來源的臨時資料表,請輸入下列指令。

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

更改下列內容:

  • LOCATION位置名稱。--location 是選用旗標。舉例來說,如果您在東京地區使用 BigQuery,就可以將該旗標的值設定為 asia-northeast1。您可以使用 .bigqueryrc 檔案設定位置的預設值。
  • SCHEMA_FILE:您本機電腦上的 JSON 結構定義檔路徑。
  • SOURCE_FORMAT:外部資料來源的格式,例如 CSV
  • BUCKET_PATH:包含資料表資料的 Cloud Storage 值區路徑,格式為 gs://bucket_name/[folder_name/]file_pattern

    您可以在 file_pattern 中指定一個星號 (*) 萬用字元,從值區中選取多個檔案。例如 gs://mybucket/file00*.parquet。詳情請參閱「Cloud Storage URI 的萬用字元支援」。

    您可以提供多個路徑,為 uris 選項指定多個值區。

    以下範例顯示有效的 uris 值:

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

    指定以多個檔案為目標的 uris 值時,所有檔案都必須共用相容的結構定義。

    如要進一步瞭解如何在 BigQuery 中使用 Cloud Storage URI,請參閱「Cloud Storage 資源路徑」。

  • QUERY:要提交至臨時資料表的查詢。

舉例來說,下列指令會使用 /tmp/sales_schema.json 結構定義檔,建立和查詢名為 sales 的臨時資料表,且此表會連結至儲存在 Cloud Storage 中的 CSV 檔案。

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

API

如要使用 API 執行查詢,請按照下列步驟操作:

  1. 建立 Job 物件
  2. 使用 JobConfiguration 物件填入 Job 物件的 configuration 部分。
  3. 使用 JobConfigurationQuery 物件填入 JobConfiguration 物件的 query 部分。
  4. 使用 ExternalDataConfiguration 物件填入 JobConfigurationQuery 物件的 tableDefinitions 部分。
  5. 呼叫 jobs.insert 方法可非同步執行查詢,而呼叫 jobs.query 方法則可同步執行查詢,並傳入 Job 物件。

Java

在嘗試這個範例之前,請先按照 BigQuery 快速入門:使用用戶端程式庫中的 Java 設定說明進行操作。詳情請參閱 BigQuery Java API 參考說明文件

如要向 BigQuery 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證機制」。

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

在嘗試這個範例之前,請先按照 BigQuery 快速入門:使用用戶端程式庫中的 Node.js 設定說明進行操作。詳情請參閱 BigQuery Node.js API 參考說明文件

如要向 BigQuery 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證機制」。

// 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

在嘗試這個範例之前,請先按照 BigQuery 快速入門:使用用戶端程式庫中的 Python 設定說明進行操作。詳情請參閱 BigQuery Python API 參考說明文件

如要向 BigQuery 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證機制」。

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)))

查詢 _FILE_NAME 虛擬欄

以外部資料來源為基礎的資料表可提供名為 _FILE_NAME 的虛擬資料欄。這個資料欄含有該列所屬檔案的完整路徑。此資料欄僅適用於參照儲存在 Cloud StorageGoogle 雲端硬碟Amazon S3Azure Blob 儲存體中的外部資料的資料表。

系統會保留 _FILE_NAME 資料欄名稱,這表示您無法在任何資料表中使用該名稱建立資料欄。如要選取 _FILE_NAME 的值,您必須使用別名。下方範例查詢示範如何透過指派別名 fn 給虛擬資料欄的方式來選取 _FILE_NAME

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

更改下列內容:

  • PROJECT_ID 是有效的專案 ID (如果您使用 Cloud Shell,或是在 Google Cloud CLI 中設定預設專案,則此為選用標記)
  • DATASET 是儲存永久外部資料表的資料集名稱
  • TABLE_NAME 是永久外部資料表的名稱

如果查詢在 _FILE_NAME 虛擬欄上設有篩選器述詞,BigQuery 會嘗試略過讀取不符合篩選條件的檔案。使用 _FILE_NAME 虛擬資料欄建構查詢述詞時,適用於 使用虛擬資料欄查詢擷取時間分區資料表 的類似建議。

後續步驟