查詢 Google 雲端硬碟資料

本文件說明如何查詢儲存在 Google 雲端硬碟外部資料表中的資料。

BigQuery 同時支援查詢個人 Google 雲端硬碟檔案和共用檔案。如要進一步瞭解 Google 雲端硬碟,請參閱 Google 雲端硬碟訓練課程和相關說明

您可以透過永久外部資料表臨時外部資料表查詢雲端硬碟資料,這些資料表是在您執行查詢時建立。

限制

如要瞭解外部資料表的相關限制,請參閱外部資料表限制

必要的角色

如要查詢 Google 雲端硬碟外部資料表,請確認您具備下列角色:

  • BigQuery 資料檢視者 (roles/bigquery.dataViewer)
  • BigQuery 使用者 (roles/bigquery.user)

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

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

所需權限

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

雲端硬碟權限

您至少必須擁有連結至外部資料表之 Google 雲端硬碟檔案的 View 權限,才能查詢 Google 雲端硬碟中的外部資料。

Compute Engine 執行個體的範圍

建立 Compute Engine 執行個體時,您可以指定執行個體的範圍清單。這些範圍會控管執行個體對 Google Cloud產品 (包括 Google 雲端硬碟) 的存取權。在 VM 上執行的應用程式會使用服務帳戶呼叫 Google Cloud API。

如果將 Compute Engine 執行個體設為以服務帳戶的形式執行,且這個服務帳戶會存取連結至 Google 雲端硬碟資料來源的外部資料表,則您必須為執行個體新增 Google 雲端硬碟的 OAuth 範圍 (https://www.googleapis.com/auth/drive.readonly)。

如需為 Compute Engine 執行個體套用範圍的相關資訊,請參閱變更執行個體的服務帳戶與存取權範圍一節。如要進一步瞭解 Compute Engine 服務帳戶,請參閱服務帳戶一文。

使用永久外部資料表查詢 Google 雲端硬碟資料

建立 Google 雲端硬碟外部資料表後,您可以使用 GoogleSQL 語法查詢資料表,就像是查詢標準 BigQuery 資料表一樣。例如:SELECT field1, field2 FROM mydataset.my_drive_table;

使用臨時資料表查詢 Google 雲端硬碟資料

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

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

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

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

建立及查詢臨時資料表

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

bq

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

  • 資料表定義檔 (儲存在本機)
  • 內嵌結構定義
  • JSON 結構定義檔 (儲存在本機)

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

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

其中:

  • LOCATION 是您的位置--location 是選用旗標。
  • 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=DRIVE_URI \
'QUERY'

其中:

  • LOCATION 是您的位置--location 是選用旗標。
  • TABLE 是要建立的臨時資料表名稱。
  • SCHEMA 是內嵌結構定義,格式為 FIELD:DATA_TYPE,FIELD:DATA_TYPE
  • SOURCE_FORMATCSVNEWLINE_DELIMITED_JSONAVROGOOGLE_SHEETS
  • DRIVE_URI 是你的 雲端硬碟 URI
  • QUERY 是要提交至臨時資料表的查詢。

舉例來說,以下指令會使用下列結構定義,建立和查詢名為 sales 且與 Google 雲端硬碟中儲存的 CSV 檔連結的臨時資料表:Region:STRING,Quarter:STRING,Total_sales:INTEGER

bq --location=US query \
--external_table_definition=sales::Region:STRING,Quarter:STRING,Total_sales:INTEGER@CSV=https://drive.google.com/open?id=1234_AbCD12abCd \
'SELECT
   Region,Total_sales
 FROM
   sales'

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

bq --location=LOCATION query \
--external_table_definition=SCHEMA_FILE@SOURCE_FORMT=DRIVE_URI \
'QUERY'

其中:

  • LOCATION 是您的位置--location 是選用旗標。
  • SCHEMA_FILE 是您本機電腦上的 JSON 結構定義檔路徑。
  • SOURCE_FILECSVNEWLINE_DELIMITED_JSONAVROGOOGLE_SHEETS
  • DRIVE_URI 是你的 雲端硬碟 URI
  • QUERY 是要提交至臨時資料表的查詢。

舉例來說,下列指令會使用 /tmp/sales_schema.json 結構定義檔,建立和查詢名為 sales 且與 Google 雲端硬碟中儲存的 CSV 檔連結的臨時資料表。

bq query \
--external_table_definition=sales::/tmp/sales_schema.json@CSV=https://drive.google.com/open?id=1234_AbCD12abCd \
'SELECT
   Total_sales
 FROM
   sales'

API

Python

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

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

from google.cloud import bigquery
import google.auth

# Create credentials with Drive & BigQuery API scopes.
# Both APIs must be enabled for your project before running this code.
credentials, project = google.auth.default(
    scopes=[
        "https://www.googleapis.com/auth/drive",
        "https://www.googleapis.com/auth/bigquery",
    ]
)

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

# Configure the external data source and query job.
external_config = bigquery.ExternalConfig("GOOGLE_SHEETS")

# Use a shareable link or grant viewing access to the email address you
# used to authenticate with BigQuery (this example Sheet is public).
sheet_url = (
    "https://docs.google.com/spreadsheets"
    "/d/1i_QCL-7HcSyUZmIbP9E6lO_T5u3HnpLe7dnpHaijg_E/edit?usp=sharing"
)
external_config.source_uris = [sheet_url]
external_config.schema = [
    bigquery.SchemaField("name", "STRING"),
    bigquery.SchemaField("post_abbr", "STRING"),
]
external_config.options.skip_leading_rows = 1  # Optionally skip header row.
external_config.options.range = (
    "us-states!A20:B49"  # Optionally set range of the sheet to query from.
)
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.

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

Java

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

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

import com.google.auth.oauth2.GoogleCredentials;
import com.google.auth.oauth2.ServiceAccountCredentials;
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.ExternalTableDefinition;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.GoogleSheetsOptions;
import com.google.cloud.bigquery.QueryJobConfiguration;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.StandardSQLTypeName;
import com.google.cloud.bigquery.TableResult;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;

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

  public static void main(String[] args) {
    // TODO(developer): Replace these variables before running the sample.
    String tableName = "MY_TABLE_NAME";
    String sourceUri =
        "https://docs.google.com/spreadsheets/d/1i_QCL-7HcSyUZmIbP9E6lO_T5u3HnpLe7dnpHaijg_E/edit?usp=sharing";
    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);
    queryExternalSheetsTemp(tableName, sourceUri, schema, query);
  }

  public static void queryExternalSheetsTemp(
      String tableName, String sourceUri, Schema schema, String query) {
    try {

      // Create credentials with Drive & BigQuery API scopes.
      // Both APIs must be enabled for your project before running this code.
      GoogleCredentials credentials =
          ServiceAccountCredentials.getApplicationDefault()
              .createScoped(
                  ImmutableSet.of(
                      "https://www.googleapis.com/auth/bigquery",
                      "https://www.googleapis.com/auth/drive"));

      // 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.newBuilder().setCredentials(credentials).build().getService();

      // Skip header row in the file.
      GoogleSheetsOptions sheetsOptions =
          GoogleSheetsOptions.newBuilder()
              .setSkipLeadingRows(1) // Optionally skip header row.
              .setRange("us-states!A20:B49") // Optionally set range of the sheet to query from.
              .build();

      // Configure the external data source and query job.
      ExternalTableDefinition externalTable =
          ExternalTableDefinition.newBuilder(sourceUri, sheetsOptions).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 | IOException e) {
      System.out.println("Query not performed \n" + e.toString());
    }
  }
}

疑難排解

錯誤字串:Resources exceeded during query execution: Google Sheets service overloaded.

這可能是暫時性錯誤,只要重新執行查詢即可修正。如果重新執行查詢後仍發生錯誤,請考慮簡化試算表,例如盡量減少公式的使用。詳情請參閱外部資料表限制

後續步驟