Google ドライブの外部テーブルを作成する

このドキュメントでは、Google ドライブに保存されているデータに外部テーブルを作成する方法について説明します。

BigQuery では、個人用ドライブ ファイルと共有ファイルの両方で外部テーブルをサポートしています。ドライブの詳細については、ドライブのトレーニングとヘルプをご覧ください。

ドライブ内にある次の形式のファイルに対して外部テーブルを作成できます。

  • カンマ区切り値(CSV)
  • JSON(改行区切り)
  • Avro
  • Google スプレッドシート

始める前に

外部テーブルを作成する前に、情報を収集して、テーブルの作成権限があることを確認します。

ドライブの URI を取得する

Google ドライブのデータソースに外部テーブルを作成するには、ドライブの URI を指定する必要があります。ドライブの URI は、ドライブデータの URL から直接取得できます。

URI の形式

  • https://docs.google.com/spreadsheets/d/FILE_ID

    または

  • https://drive.google.com/open?id=FILE_ID

ここで、FILE_ID はドライブ ファイルの英数字の ID です。

ドライブへのアクセスを認証して有効にする

ドライブ内でホストされているデータにアクセスするには、追加の OAuth スコープが必要です。BigQuery に対する認証を行いドライブへのアクセスを有効にするには、次の操作を行います。

コンソール

Google Cloud コンソールで外部テーブルを作成する場合は、ウェブベースの認証手順に沿って操作します。プロンプトが表示されたら、[許可] をクリックして、BigQuery クライアント ツールにドライブへのアクセスを許可します。

gcloud

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. 次のコマンドを入力して、Google Cloud CLI が最新バージョンであることを確認します。

    gcloud components update
    
  3. 次のコマンドを入力して、ドライブの認証を行います。

    gcloud auth login --enable-gdrive-access
    
  4. API

    BigQuery のスコープに加えて、適切な ドライブの OAuth スコープをリクエストします。

    1. gcloud auth login --enable-gdrive-access コマンドを実行してログインします。
    2. gcloud auth print-access-token コマンドを実行して、API に使用されるドライブ スコープで OAuth アクセス トークンを取得します。

    Python

    1. OAuth クライアント ID を作成します

    2. ローカル環境で、必要なスコープを使用して次の手順によりアプリケーションのデフォルト認証情報(ADC)を設定します。

      1. Google Cloud CLI をインストールし、次のコマンドを実行して初期化します。

        gcloud init
      2. Google アカウントのローカル認証情報を作成します。

        gcloud auth application-default login \
            --client-id-file=CLIENT_ID_FILE \
            --scopes=https://www.googleapis.com/auth/drive,https://www.googleapis.com/auth/cloud-platform

        CLIENT_ID_FILE は、OAuth クライアント ID を含むファイルに置き換えます。

        詳細については、gcloud CLI で提供されるユーザー認証情報をご覧ください。

    Java

    1. OAuth クライアント ID を作成します

    2. ローカル環境で、必要なスコープを使用して次の手順によりアプリケーションのデフォルト認証情報(ADC)を設定します。

      1. Google Cloud CLI をインストールし、次のコマンドを実行して初期化します。

        gcloud init
      2. Google アカウントのローカル認証情報を作成します。

        gcloud auth application-default login \
            --client-id-file=CLIENT_ID_FILE \
            --scopes=https://www.googleapis.com/auth/drive,https://www.googleapis.com/auth/cloud-platform

        CLIENT_ID_FILE は、OAuth クライアント ID を含むファイルに置き換えます。

        詳細については、gcloud CLI で提供されるユーザー認証情報をご覧ください。

    必要なロール

    外部テーブルを作成するには、bigquery.tables.create BigQuery Identity and Access Management(IAM)権限が必要です。

    この権限は、次の Identity and Access Management 事前定義ロールに含まれています。

    • BigQuery データ編集者(roles/bigquery.dataEditor
    • BigQuery データオーナー(roles/bigquery.dataOwner
    • BigQuery 管理者(roles/bigquery.admin

    これらのロールのいずれかのプリンシパルでない場合は、アクセス権の付与または外部テーブルの作成を管理者に依頼してください。

    BigQuery での Identity and Access Management のロールと権限の詳細については、事前定義ロールと権限をご覧ください。

    外部テーブルを作成する

    外部データソースにリンクされた永続テーブルは、次の方法で作成します。

    • Google Cloud コンソールを使用する
    • bq コマンドライン ツールの mk コマンドを使用する
    • tables.insert API メソッドを使用する際に ExternalDataConfiguration を作成する
    • クライアント ライブラリを使用する

    外部テーブルを作成するには:

    コンソール

    1. Google Cloud コンソールで、[BigQuery] ページを開きます。

    [BigQuery] に移動

    1. [エクスプローラ] パネルでプロジェクトを開いて、データセットを選択します。

    2. アクション オプションを開いて、[開く] をクリックします。

    3. 詳細パネルで [テーブルを作成] をクリックします。

    4. [テーブルの作成] ページの [ソース] セクションで、次の操作を行います。

      • [テーブルの作成元] で [ドライブ] を選択します。

      • [ドライブの URI を選択] フィールドに ドライブの URI を入力します。ドライブの URI にはワイルドカードを使用できません。

      • [ファイル形式] でデータの形式を選択します。ドライブのデータで有効な形式は次のとおりです。

        • カンマ区切り値(CSV)
        • JSON(改行区切り)
        • Avro
        • スプレッドシート
    5. (省略可)[スプレッドシート] を選択した場合、[シート範囲(省略可)] ボックスで、クエリを実行するシートとセル範囲を指定します。シート名を指定するか、セル範囲として sheet_name!top_left_cell_id:bottom_right_cell_id を指定できます。たとえば、「Sheet1!A1:B20」と指定します。[シートの範囲] を指定しない場合、ファイルの最初のシートが使用されます。

    6. [テーブルの作成] ページの [送信先] セクションで、次の操作を行います。

      • [データセット名] で該当するデータセットを選択し、[テーブル名] フィールドに BigQuery で作成するテーブルの名前を入力します。

        データセットを選択

      • [テーブルタイプ] が [外部テーブル] に設定されていることを確認します。

    7. [スキーマ] セクションにスキーマ定義を入力します。

      • JSON または CSV ファイルの場合、[自動検出] オプションをオンにしてスキーマの自動検出を有効にできます。Datastore エクスポート、Firestore エクスポート、Avro ファイルには、[自動検出] を使用できません。これらのファイル形式のスキーマ情報は、自己記述型のソースデータから自動的に取得されます。
      • スキーマ情報を手動で入力します。
        • [テキストとして編集] を有効にし、テーブル スキーマを JSON 配列として入力します。注: 既存のテーブルのスキーマを JSON 形式で表示するには、bq コマンドライン ツールに bq show --format=prettyjson DATASET.TABLE コマンドを入力します。
        • [フィールドを追加] を使用して、スキーマを手動で入力します。
    8. [テーブルを作成] をクリックします。

    9. 必要に応じて、自分のアカウントを選択して [許可] をクリックし、BigQuery クライアント ツールにドライブへのアクセスを許可します。

    これで、標準 BigQuery テーブルの場合と同じようにテーブルに対してクエリを実行できます。ただし、外部データソースの制限は適用されます。

    クエリが完了した後、結果は、CSV または JSON としてダウンロード、テーブルとして保存、スプレッドシートに保存、のいずれかを行うことが可能です。詳しくは、データのダウンロード、保存、エクスポートをご覧ください。

    bq

    bq mk コマンドを使用して bq コマンドライン ツールでテーブルを作成します。bq コマンドライン ツールを使用して外部データソースにリンクするテーブルを作成するには、以下を使用してテーブルのスキーマを識別します。

    • テーブル定義ファイル(ローカルマシンに保存)
    • インライン スキーマの定義
    • JSON スキーマ ファイル(ローカルマシンに保存)

    テーブル定義ファイルを使用して、ドライブのデータソースにリンクする永続テーブルを作成するには、次のコマンドを入力します。

    bq mk \
    --external_table_definition=DEFINITION_FILE \
    DATASET.TABLE

    ここで

    • DEFINITION_FILE は、ローカルマシン上のテーブル定義ファイルのパスです。
    • DATASET は、テーブルを含むデータセットの名前です。
    • TABLE は、作成するテーブルの名前です。

    たとえば、mytable_def という名前のテーブル定義ファイルを使用して、mytable という名前の永続テーブルを作成するコマンドは次のとおりです。

    bq mk --external_table_definition=/tmp/mytable_def mydataset.mytable
    

    インライン スキーマ定義を使用して、外部データソースにリンクする永続テーブルを作成するには、次のコマンドを入力します。

    bq mk \
    --external_table_definition=SCHEMA@SOURCE_FORMAT=DRIVE_URI \
    DATASET.TABLE

    ここで

    • SCHEMA は、FIELD:DATA_TYPE,FIELD:DATA_TYPE という形式のスキーマ定義です。
    • SOURCE_FORMATCSVNEWLINE_DELIMITED_JSONAVRO、または GOOGLE_SHEETS です。
    • DRIVE_URI は、使用するドライブの URI です。
    • DATASET は、テーブルを含むデータセットの名前です。
    • TABLE は、作成するテーブルの名前です。

    たとえば、次のコマンドを実行すると、スキーマ定義 Region:STRING,Quarter:STRING,Total_sales:INTEGER を使用して、ドライブに保存されたスプレッドシート ファイルにリンクする永続テーブルが sales という名前で作成されます。

    bq mk \
    --external_table_definition=Region:STRING,Quarter:STRING,Total_sales:INTEGER@GOOGLE_SHEETS=https://drive.google.com/open?id=1234_AbCD12abCd \
    mydataset.sales
    

    JSON スキーマ ファイルを使用して、外部データソースにリンクする永続テーブルを作成するには、次のコマンドを入力します。

    bq mk \
    --external_table_definition=SCHEMA_FILE@SOURCE_FORMAT=DRIVE_URI \
    DATASET.TABLE

    ここで

    • SCHEMA_FILE は、ローカルマシン上の JSON スキーマ ファイルのパスです。
    • SOURCE_FORMATCSVNEWLINE_DELIMITED_JSONAVRO、または GOOGLE_SHEETS です。
    • DRIVE_URI は、使用するドライブの URI です。
    • DATASET は、テーブルを含むデータセットの名前です。
    • TABLE は、作成するテーブルの名前です。

    テーブル定義ファイルスプレッドシート固有の構成が含まれている場合は、先行する行をスキップして、定義済みのシート範囲を指定できます。

    次の例では、/tmp/sales_schema.json スキーマ ファイルを使用して、ドライブに保存された CSV ファイルにリンクする sales という名前のテーブルを作成します。

    bq mk \
    --external_table_definition=/tmp/sales_schema.json@CSV=https://drive.google.com/open?id=1234_AbCD12abCd \
    mydataset.sales
    

    永続テーブルが作成されると、標準の BigQuery テーブルと同じようにテーブルに対してクエリを実行できます。ただし、外部データソースの制限の影響を受けます。

    クエリが完了した後、結果は、CSV または JSON としてダウンロード、テーブルとして保存、スプレッドシートに保存、のいずれかを行うことが可能です。詳しくは、データのダウンロード、保存、エクスポートをご覧ください。

    API

    tables.insert API メソッドを使用する際に ExternalDataConfiguration を作成します。schema プロパティを指定するか autodetect プロパティを true に設定して、サポートされているデータソースのスキーマの自動検出を有効にします。

    Python

    from google.cloud import bigquery
    import google.auth
    
    credentials, project = google.auth.default()
    
    # Construct a BigQuery client object.
    client = bigquery.Client(credentials=credentials, project=project)
    
    # TODO(developer): Set dataset_id to the ID of the dataset to fetch.
    # dataset_id = "your-project.your_dataset"
    
    # Configure the external data source.
    dataset = client.get_dataset(dataset_id)
    table_id = "us_states"
    schema = [
        bigquery.SchemaField("name", "STRING"),
        bigquery.SchemaField("post_abbr", "STRING"),
    ]
    table = bigquery.Table(dataset.table(table_id), schema=schema)
    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]
    options = external_config.google_sheets_options
    assert options is not None
    options.skip_leading_rows = 1  # Optionally skip header row.
    options.range = (
        "us-states!A20:B49"  # Optionally set range of the sheet to query from.
    )
    table.external_data_configuration = external_config
    
    # Create a permanent table linked to the Sheets file.
    table = client.create_table(table)  # Make an API request.
    
    # Example query to find states starting with "W".
    sql = 'SELECT * FROM `{}.{}` WHERE name LIKE "W%"'.format(dataset_id, table_id)
    
    results = client.query_and_wait(sql)  # Make an API request.
    
    # Wait for the query to complete.
    w_states = list(results)
    print(
        "There are {} states with names starting with W in the selected range.".format(
            len(w_states)
        )
    )

    Java

    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.TableId;
    import com.google.cloud.bigquery.TableInfo;
    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 permanent table
    public class QueryExternalSheetsPerm {
    
      public static void main(String[] args) {
        // TODO(developer): Replace these variables before running the sample.
        String datasetName = "MY_DATASET_NAME";
        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.%s WHERE name LIKE 'W%%'", datasetName, tableName);
        queryExternalSheetsPerm(datasetName, tableName, sourceUri, schema, query);
      }
    
      public static void queryExternalSheetsPerm(
          String datasetName, String tableName, String sourceUri, Schema schema, String query) {
        try {
    
          GoogleCredentials credentials =
              ServiceAccountCredentials.getApplicationDefault();
    
          // 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();
    
          TableId tableId = TableId.of(datasetName, tableName);
          // Create a permanent table linked to the Sheets file.
          ExternalTableDefinition externalTable =
              ExternalTableDefinition.newBuilder(sourceUri, sheetsOptions).setSchema(schema).build();
          bigquery.create(TableInfo.of(tableId, externalTable));
    
          // Example query to find states starting with 'W'
          TableResult results = bigquery.query(QueryJobConfiguration.of(query));
    
          results
              .iterateAll()
              .forEach(row -> row.forEach(val -> System.out.printf("%s,", val.toString())));
    
          System.out.println("Query on external permanent table performed successfully.");
        } catch (BigQueryException | InterruptedException | IOException e) {
          System.out.println("Query not performed \n" + e.toString());
        }
      }
    }

    外部テーブルにクエリを実行する

    詳細については、ドライブデータのクエリをご覧ください。

    _FILE_NAME 疑似列

    外部データソースに基づくテーブルは、_FILE_NAME という名前の疑似列を提供します。この列には、行が属するファイルへの完全修飾パスが含まれます。この列は、Cloud StorageGoogle ドライブに保存されている外部データを参照するテーブルでのみ使用できます。

    _FILE_NAME という列名は予約されています。つまり、この名前を持つ列はどのテーブルにも作成できません。