BigQueryにデータセットがあります。このデータセットには複数のテーブルが含まれています。
BigQuery APIを使用してプログラムで次の手順を実行しています。
データセット内のテーブルのクエリ-応答が大きすぎるため、allowLargeResultsパラメータを有効にして、応答を宛先テーブルに転送しています。
次に、宛先テーブルからGCSバケットにデータをエクスポートしています。
要件:
ステップ2でプロセスが失敗した場合、このステップを再実行したいと思います。
しかし、再実行する前に、「xyz」という名前の特定の宛先テーブルがデータセットにすでに存在することを確認/確認したいと思います。
存在する場合は、手順2を再実行します。
存在しない場合はfooをしたいです。
これどうやってするの?
前もって感謝します。
ここにpythonスニペットがあり、テーブルが存在するかどうかを確認します(プロセスでテーブルを削除する-注意!):
def doesTableExist(project_id, dataset_id, table_id):
bq.tables().delete(
projectId=project_id,
datasetId=dataset_id,
tableId=table_id).execute()
return False
または、プロセスでテーブルを削除したくない場合は、次の方法を試すことができます。
def doesTableExist(project_id, dataset_id, table_id):
try:
bq.tables().get(
projectId=project_id,
datasetId=dataset_id,
tableId=table_id).execute()
return True
except HttpError, err
if err.resp.status <> 404:
raise
return False
bq
がどこから来たかを知りたい場合は、ここからbuild_bq_client
を呼び出すことができます: http://code.google.com/p/bigquery-e2e/source/browse/ samples/ch12/auth.py
一般に、これを使用してテーブルを変更するジョブを実行する必要があるかどうかをテストする場合は、とにかくジョブを実行し、WRITE_TRUNCATE
を書き込み処理として使用することをお勧めします。
別のアプローチとして、予測可能なジョブIDを作成し、そのIDでジョブを再試行することができます。ジョブがすでに存在する場合、ジョブはすでに実行されています(ただし、ジョブが失敗していないことを確認するために、再度確認することをお勧めします)。
Alex Fのソリューションはv0.27で機能しますが、それ以降のバージョンでは機能しません。 v0.28 +に移行 するために、以下のソリューションが機能します。
from google.cloud import bigquery
project_nm = 'gc_project_nm'
dataset_nm = 'ds_nm'
table_nm = 'tbl_nm'
client = bigquery.Client(project_nm)
dataset = client.dataset(dataset_nm)
table_ref = dataset.table(table_nm)
def if_tbl_exists(client, table_ref):
from google.cloud.exceptions import NotFound
try:
client.get_table(table_ref)
return True
except NotFound:
return False
if_tbl_exists(client, table_ref)
楽しい:
def doesTableExist(bigquery, project_id, dataset_id, table_id):
try:
bigquery.tables().get(
projectId=project_id,
datasetId=dataset_id,
tableId=table_id).execute()
return True
except Exception as err:
if err.resp.status != 404:
raise
return False
例外的に編集があります。
タヒールの答えはおそらく現時点でおそらく最も正しいです
しかし、上記のIvanからのコメントを検討していました。「404は、さまざまな理由でリソースが存在しないことを意味することもあります」。そのため、メタデータクエリを常に正常に実行し、結果を返すソリューションを次に示します。
常にクエリを実行する必要があるため、最速ではありません。bigqueryは小さなクエリに対してオーバーヘッドを持っています
以前に見たトリックは、(テーブル)オブジェクトに対してinformation_schema
をクエリし、オブジェクトが返さない場合でもレコードが常に返されることを保証する偽のクエリに対してunion
を実行することです。 LIMIT 1
と、存在する場合に返される単一のレコードがテーブルを表すことを保証するための順序付けもあります。以下のコードのSQLを参照してください。
__table_summary__
はサポートしています__table_summary__
をクエリできないため、データセットが必要です_TABLE_SUFFIX
を除いて、 https://cloud.google.com/bigquery/docsを参照)。/querying-wildcard-tables )#!/usr/bin/env python
"""
Inline SQL way to check a table exists in Bigquery
e.g.
print(table_exists(dataset_name='<dataset_goes_here>', table_name='<real_table_name'))
True
print(table_exists(dataset_name='<dataset_goes_here>', table_name='imaginary_table_name'))
False
"""
from __future__ import print_function
from google.cloud import bigquery
def table_exists(dataset_name, table_name):
client = bigquery.Client()
query = """
SELECT table_exists FROM
(
SELECT true as table_exists, 1 as ordering
FROM __TABLES_SUMMARY__ WHERE table_id = @table_name
UNION ALL
SELECT false as table_exists, 2 as ordering
) ORDER by ordering LIMIT 1"""
query_params = [bigquery.ScalarQueryParameter('table_name', 'STRING', table_name)]
job_config = bigquery.QueryJobConfig()
job_config.query_parameters = query_params
if dataset_name is not None:
dataset_ref = client.dataset(dataset_name)
job_config.default_dataset = dataset_ref
query_job = client.query(
query,
job_config=job_config
)
results = query_job.result()
for row in results:
# There is only one row because LIMIT 1 in the SQL
return row.table_exists
ここでexists()
を使用して、データセットがテーブルと同じであるかどうかを確認できます BigQuery existのドキュメント
my_bigquery
はクラスのインスタンスですgoogle.cloud.bigquery.Client
(認証済みで、プロジェクトに関連付けられています):
my_bigquery.dataset(dataset_name).table(table_name).exists() # returns boolean
GETリクエストを介してテーブルの存在をテストするためのAPI呼び出しを行います
0.27のGoogle Bigquery Python module