web-dev-qa-db-ja.com

BigQuery-テーブルがすでに存在するかどうかを確認します

BigQueryにデータセットがあります。このデータセットには複数のテーブルが含まれています。

BigQuery APIを使用してプログラムで次の手順を実行しています。

  1. データセット内のテーブルのクエリ-応答が大きすぎるため、allowLargeResultsパラメータを有効にして、応答を宛先テーブルに転送しています。

  2. 次に、宛先テーブルからGCSバケットにデータをエクスポートしています。

要件:

  • ステップ2でプロセスが失敗した場合、このステップを再実行したいと思います。

  • しかし、再実行する前に、「xyz」という名前の特定の宛先テーブルがデータセットにすでに存在することを確認/確認したいと思います。

  • 存在する場合は、手順2を再実行します。

  • 存在しない場合はfooをしたいです。

これどうやってするの?

前もって感謝します。

15
activelearner

ここに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でジョブを再試行することができます。ジョブがすでに存在する場合、ジョブはすでに実行されています(ただし、ジョブが失敗していないことを確認するために、再度確認することをお勧めします)。

9
Jordan Tigani

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)
12
tarheel

楽しい:

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

例外的に編集があります。

1
abdelhadi danba

インラインSQL代替

タヒールの答えはおそらく現時点でおそらく最も正しいです

しかし、上記のIvanからのコメントを検討していました。「404は、さまざまな理由でリソースが存在しないことを意味することもあります」。そのため、メタデータクエリを常に正常に実行し、結果を返すソリューションを次に示します。

常にクエリを実行する必要があるため、最速ではありません。bigqueryは小さなクエリに対してオーバーヘッドを持っています

以前に見たトリックは、(テーブル)オブジェクトに対してinformation_schemaをクエリし、オブジェクトが返さない場合でもレコードが常に返されることを保証する偽のクエリに対してunionを実行することです。 LIMIT 1と、存在する場合に返される単一のレコードがテーブルを表すことを保証するための順序付けもあります。以下のコードのSQLを参照してください。

  • Bigqueryの標準SQLはISOに準拠しているというドキュメントの主張にもかかわらず、それらはinformation_schemaをサポートしていませんが、__table_summary__はサポートしています
  • データセットを指定しないと__table_summary__をクエリできないため、データセットが必要です
  • sQLインジェクションの問題がないとオブジェクト名をパラメーター化できないため、データセットはSQLのパラメーターではありません(魔法の_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
0
Davos

ここでexists()を使用して、データセットがテーブルと同じであるかどうかを確認できます BigQuery existのドキュメント

0
Ghizlane Lotfi

my_bigqueryはクラスのインスタンスですgoogle.cloud.bigquery.Client(認証済みで、プロジェクトに関連付けられています):

my_bigquery.dataset(dataset_name).table(table_name).exists()  # returns boolean

GETリクエストを介してテーブルの存在をテストするためのAPI呼び出しを行います

ソース: https://googlecloudplatform.github.io/google-cloud-python/0.24.0/bigquery-table.html#google.cloud.bigquery.table.Table.exists

0.27のGoogle Bigquery Python module

0
Alex F