SELECT および INSERT クエリを実行できます。テーブル構造は、BigQuery のテーブルスキーマから自動的に推論されます。
読み取りには BigQuery REST API (tabledata.list) を使用するため、読み取り可能なのはネイティブテーブルのみです (ビュー、materialized view、外部テーブルは読み取れません) 。書き込みにはストリーミング挿入 (tabledata.insertAll) を使用します。この機能を使用するには、プロジェクトで課金を有効にする必要があります。
構文
引数
project、dataset、table、access_token 引数は、key = value 形式でも指定できます。位置引数はこの順序でこれらのスロットを埋めます。引数を位置指定とキー指定の両方で指定した場合、または同じキーを 2 回指定した場合はエラーになります。
次の引数は、key = value 形式 (または名前付きコレクションのキー) で指定できます。
認証
- アクセストークン。
gcloud auth print-access-tokenなどで取得した有効な OAuth 2.0 アクセストークンを使用します。トークンは短時間で失効する (通常は1時間後) ため、この方法は対話的な利用に最適です。 - サービスアカウントキー (サーバーでの利用に推奨) 。Google Cloud IAM で作成したキーファイルの内容を、
service_account_key引数で渡します。ClickHouse はこのキーで JWT に署名し、アクセストークンと交換して自動的に更新します。 - リフレッシュトークン。
client_id、client_secret、refresh_tokenを渡します。たとえば、gcloud auth application-default loginの実行後、~/.config/gcloud/application_default_credentials.jsonから取得できます。
BigQuery テーブルエンジンまたは CREATE TABLE ... AS bigquery(...) を使用) は、そのコレクションの依存先として登録されるため、テーブルが存在する間は DROP NAMED COLLECTION を実行できません。
型マッピング
注:
- BigQuery の
DATETIMEにはタイムゾーンがありません。表示値がサーバーのタイムゾーンに依存しないよう、DateTime64(6, 'UTC')にマッピングされます。 NULLABLEのRECORDはNullable(Tuple(...))にマッピングされるため、レコード全体のNULLはデフォルト値からなるTupleに折りたたまれず、NULLとして保持されます。NULLの配列 (または空の配列) は空の配列になります。これは ClickHouse ではArrayをNullable内に含められないためです。BigQuery の配列にNULL要素を含めることはできません (ARRAY<T>はARRAY<T NOT NULL>と同等です) 。そのため、REPEATEDフィールドの要素型はNullableではありません (Array(T)、またはRECORD要素の場合はArray(Tuple(...))) 。tabledata.listレスポンス内のNULL要素は不正な入力として拒否されます。bigqueryテーブル関数を介したNullable(Tuple(...))カラムの読み書きは、追加設定なしで行えます。このようなカラムを含む永続的なBigQueryエンジンテーブルを作成するには、構造を推論する場合も明示的に宣言する場合も、他のNullable(Tuple)カラムと同様にenable_nullable_tuple_type設定が必要です。カラムを明示的に宣言する場合は、設定を不要にするため、RECORDフィールドを通常のTuple(...)として宣言することもできますが、その場合レコード全体のNULLはデフォルトのタプルに強制変換されます。推論された型との差異として許容されるのは、RECORDのTupleをラップするNullableを削除することだけであり、同じレコードに限られます。null 許容性を別の (内側または外側の) レコードに移すことはできません。GEOGRAPHYは Geometry にマッピングされます。BigQuery はGEOGRAPHY値を WKT テキストとして転送します。読み取り時には、これがGeometryの対応する代替型 (Point、MultiPoint、Ring、LineString、MultiLineString、Polygon、MultiPolygonのVariant) に解析され、書き込み時には WKT にシリアル化されます。GEOMETRYCOLLECTIONおよび空のジオメトリ (POINT EMPTYなど) に対応するGeometryはないため、このような値を含む行を読み取るとエラーが発生します。Variantは単体でNULLを保持できるため、NULLABLEのGEOGRAPHYフィールドはNullable(Geometry)ではなくGeometryにマッピングされ、NULLも往復変換されます。JSONは JSON データ型ではなくStringにマッピングされます。これは、ClickHouse のJSON型が最上位レベルではオブジェクト ({...}) のみを受け入れる一方、BigQuery のJSON値はスカラー、配列、nullなど任意の JSON 値になり得るためであり、このような値を含むテーブルは読み取れなくなります。さらに、JSONはNullableでラップできないため、NULLABLEカラムの SQLNULLは保持されません。Stringマッピングは情報を損なわず、最上位オブジェクトはCAST(value AS JSON)で変換できます。- 整数部が 38 桁を超える
BIGNUMERIC値はDecimal(76, 38)に収まらず、エラーになります。 DateTime64/Date32の範囲 (1900~2299 年) 外のTIMESTAMPおよびDATE値はサポートされません。RANGEカラムは読み取り専用です。tabledata.insertAllはRANGE<T>値として構造化された{start, end}オブジェクトを想定しますが、これはStringマッピングから再構築できないため、RANGEカラムへの挿入はエラーになります。INT64値は、API が JSON 数値を double として解析するため、そうしなければ[-2^53 + 1, 2^53 - 1]の範囲外の値が破損することから、10 進数文字列としてtabledata.insertAllに送信されます。
例
gcloud のトークンを使用して、公開データセットを読み取ります。
制限事項
- 読み取れるのはネイティブ BigQuery テーブルのみです。ビューおよび外部テーブルを読み取るには BigQuery クエリジョブを実行する必要がありますが、この関数では実行しません。
RANGEカラムは (Stringとして) 読み取れますが、書き込むことはできません。RANGEカラムへの挿入はエラーになります。GEOMETRYCOLLECTIONまたは空のジオメトリであるGEOGRAPHY値は、Geometry型で表現できないため、それを含む行を読み取るとエラーになります。REQUIREDGEOGRAPHYフィールドにNULLのGeometryを書き込むこと、またはREPEATEDGEOGRAPHYフィールドの要素として書き込むことは、BigQuery ではその位置にNULLを許可しないため拒否されます。- 述語はプッシュダウンされません。
tabledata.listはテーブルの行を一覧するだけで、フィルタリングパラメータをまったく提供しません (ページネーション、カラム選択、フォーマットのオプションのみを受け取ります) 。フィルタリングには BigQuery クエリジョブの実行が必要ですが、この関数では実行しません。したがって、WHERE条件は行のダウンロード後に ClickHouse で適用されます。転送データ量を削減するには、カラム選択を使用してください。 - 一方、
LIMITは読み取るデータ量を削減します。ページはmaxResultsをmax_block_sizeに設定して遅延的にリクエストされ、クエリに十分な行数が得られると、それ以上のページはリクエストされません。単純なLIMIT n(WHERE、GROUP BY、ORDER BYがなく、nがmax_block_size未満) の場合、ClickHouse はmax_block_sizeをnに下げるため、ちょうどn行に対して 1 回だけリクエストが行われます。それ以外の場合、読み取りは制限を超えた最初のページ境界で停止し、超過分は 1 ページ未満です。 - 読み取りでは、明示的なカラムリストを
tabledata.listに渡すことで、クエリ分析時に確認したスキーマに固定します。カラムリストがリクエスト URL の長さ制限を超える非常に多数のカラムを対象とする読み取り (たとえば、数千カラムあるテーブルに対するSELECT *) では、固定せずに読み取るのではなくクエリが拒否されます (固定されていない読み取りは、同時実行のスキーマ変更により不整合になる可能性があります) 。リストに収まるよう、選択するカラムを減らしてください。同じ URL 長制限は、ページネーションされた各リクエストの前にも確認されます (各ページには不透明なpageTokenが含まれます) 。そのため、後続ページが制限に収まらない読み取りは、途中で失敗するのではなく同じエラーで拒否されます。 - BigQuery テーブルのスキーマを読み取った後にテーブルが変更された場合、不一致のデータを黙って返したり書き込んだりする代わりに、クエリは拒否されます。ライブスキーマは読み取りの直前に再取得され、分析時のスキーマと比較されます。また、
INSERTが最初の行のストリーミングを開始する前にも再度比較されます。この確認から後続のリクエストまでの間にスキーマが変更される可能性は、スキーマとデータが別々の REST リクエストで取得されるため、排除できません。 - 比較対象は、クエリの分析に使用されたスキーマスナップショットです。これはテーブル関数がその構造を解決するときに取得されます。永続テーブル (
BigQueryengine テーブル、またはCREATE TABLE ... AS bigquery(...)で作成され、同様にカラムを永続化するテーブル) の場合は、CREATE、ATTACH、またはサーバー再起動後の最初の読み取りまたは書き込み時に取得されます。テーブルメタデータには BigQuery スキーマではなくマッピングされた ClickHouse カラムが永続化されるため、テーブルがデタッチされている間 (またはサーバー停止中) に行われたスキーマ変更は拒否されず、次のクエリで採用されます。宣言されたカラムは引き続きライブスキーマに対して検証され、行もそのスキーマに従ってデコードされるため、マッピングされた ClickHouse 型を維持する変更 (たとえばSTRINGからBYTES) は、同じカラム型のまま新しい型の規則に従って読み取られます。 - ストリーミング挿入で書き込まれた行は BigQuery のストリーミングバッファに格納され、後続の読み取りで表示されるまでに時間がかかる場合があります。
- 大きな
INSERTはバッチに分割してtabledata.insertAllに送信されます。各リクエストは最大 500 行で、BigQuery の 10 MB のリクエストサイズ制限を超えないようにも分割されます (この制限を超える単一行は、明確なエラーで拒否されます) 。 - 書き込みはアトミックではなく、1 回の
tabledata.insertAllリクエストでも一部のみ成功する可能性があります。BigQuery はリクエスト内の一部の行をコミットする一方、他の行をinsertErrorsとして拒否する場合があります。また、各リクエストは互いに独立してコミットされるため、先行するバッチが受け入れられた後に後続のバッチが拒否されることもあります。どちらの場合もクエリはエラーを報告しますが、すでにコミットされた行は BigQuery に残ります。重複を抑えるため、各行にはクエリ ID とストリーム内での行の序数位置から生成した安定したinsertIdを付与して送信します。BigQuery はこれを使用して、ストリーミング挿入ウィンドウ内でベストエフォートによる重複排除を行います。BigQuery のinsertIdの 128 文字制限を超えるquery_idは、固定長のプレフィックスにハッシュ化され、そのquery_idに対して安定した値となります。insertIdは序数位置に依存するため、重複排除が確実に行われるのは、再実行時に行が同じ順序で生成される場合に限られます。バッチのトランスポートレベルでの再試行は常に安全ですが、同じquery_idで同じINSERTを再実行した場合に重複排除されるのは、行が同じ順序で提示される場合のみです (たとえば、単一スレッドの insert、またはそれ以外に決定論的な順序付けの場合です。試行間で chunk の順序が変わる可能性がある並列INSERT ... SELECTでは、max_threads = 1およびmax_insert_threads = 1を設定してください) 。