👶
BigQuery Streaming Insert したデータは最大 90 分間 UPDATE/DELETE できない
はじめに
BigQuery の Python クライアント(google-cloud-bigquery)で Streaming Insert(insert_rows_json)を使って挿入したデータは、最大 90 分間 UPDATE/DELETE ができません。
この仕様と対処法を解説します(知っている方も多い気がしますが、備忘録です)。
BigQuery Python クライアントのデータ挿入方式
google-cloud-bigquery ライブラリには、大きく分けて 2 種類のデータ挿入方式があります:
| 方式 | メソッド | 特徴 |
|---|---|---|
| Streaming Insert |
insert_rows(), insert_rows_json()
|
低レイテンシ |
| Load Job |
load_table_from_json(), load_table_from_file() など |
バッチ処理 |
Streaming Insert の制約
Streaming Insert で挿入されたデータは、一時的に「ストリーミングバッファ」に格納されます。
このバッファ内のデータには以下の制約があります:
- ✅ SELECT は可能(データは見える)
- ❌ UPDATE は不可能
- ❌ DELETE も不可能
バッファからマネージドストレージにフラッシュされるまで、最大 90 分待つ必要があります。
対処法:Load Job を使う
Load Job はデータを直接マネージドストレージに書き込むため、ストリーミングバッファを経由しません。INSERT 直後に UPDATE/DELETE が可能です。
コード例
# Streaming Insert(INSERT 後に UPDATE/DELETE 不可)
def insert_rows(self, rows):
errors = self.client.insert_rows_json(self.table_id, rows)
if errors:
raise RuntimeError(f"InsertRowsError: {errors}")
# Load Job(INSERT 後に UPDATE/DELETE 可能)
def insert_rows(self, rows):
job_config = bigquery.LoadJobConfig(
source_format=bigquery.SourceFormat.NEWLINE_DELIMITED_JSON,
write_disposition=bigquery.WriteDisposition.WRITE_APPEND,
)
job = self.client.load_table_from_json(rows, self.table_id, job_config=job_config)
job.result()
両方式の比較
| 項目 | Streaming Insert | Load Job |
|---|---|---|
| INSERT 後の DML | 最大 90 分待機 | 即座に可能 |
| レイテンシ | 数秒 | 数秒〜十数秒 |
| 制限 | なし | 1,500 jobs/table/日 |
| コスト | $0.05/GB | 無料 |
まとめ
- Streaming Insert(
insert_rows_json)で挿入したデータは最大 90 分間 UPDATE/DELETE できない - INSERT 後に DML 操作が必要な場合は Load Job(
load_table_from_json)を使う
Discussion