BigQuery - проверьте, существует ли таблица
У меня есть набор данных в BigQuery. Этот набор данных содержит несколько таблиц.
Я выполняю следующие шаги программным образом с помощью API BigQuery:
-
Запрос таблиц в наборе данных. Поскольку мой ответ слишком велик, я включаю параметр allowLargeResults и перенаправляю свой ответ на таблицу назначения.
-
Затем я экспортирую данные из таблицы адресатов в ведро GCS.
Требования:
-
Предположим, что мой процесс завершился неудачно на шаге 2, я хотел бы повторно запустить этот шаг.
-
Но перед повторным запуском я хотел бы проверить/проверить, что определенная таблица назначения с именем "xyz" уже существует в наборе данных.
-
Если он существует, я хотел бы повторно запустить шаг 2.
-
Если этого не существует, я хотел бы сделать foo.
Как я могу это сделать?
Спасибо заранее.
Ответы
Ответ 1
Вот фрагмент кода 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
в качестве расположения записи.
Другим подходом может быть создание предсказуемого идентификатора задания и повторное выполнение задания с этим идентификатором. Если задание уже существует, задание уже выполнено (однако вы можете проверить его еще раз, чтобы убедиться, что задание не провалилось).
Ответ 2
Решение 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)
Ответ 3
Enjoy:
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
Существует исключение редактирования.
Ответ 4
С my_bigquery
является экземпляром класса google.cloud.bigquery.Client
(уже аутентифицированного и связанного с проектом):
my_bigquery.dataset(dataset_name).table(table_name).exists() # returns boolean
Он выполняет вызов API для проверки существования таблицы с помощью запроса GET
Источник: https://googlecloudplatform.github.io/google-cloud-python/0.24.0/bigquery-table.html#google.cloud.bigquery.table.Table.exists
Он работает для меня с использованием 0,27 модуля Google Bigquery Python.
Ответ 5
Встроенная альтернатива SQL
Ответ tarheel, пожалуй, самый правильный на данный момент
но я рассматривал комментарий Ивана выше, что "404 может также означать, что ресурс не существует по ряду причин", так что вот решение, которое всегда должно успешно выполнять запрос метаданных и возвращать результат.
Это не самый быстрый, потому что он всегда должен выполнить запрос, bigquery имеет накладные расходы для небольших запросов
Уловка, которую я видел ранее, состоит в том, чтобы запросить information_schema
для (табличного) объекта и union
его с поддельным запросом, который гарантирует, что запись всегда возвращается, даже если объект этого не делает. Существует также LIMIT 1
и порядок, чтобы гарантировать, что одна возвращенная запись представляет таблицу, если она существует. Смотрите SQL в коде ниже.
- Несмотря на заявления doc о том, что стандарт SQL Bigquery совместим с 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
Ответ 6
теперь вы можете использовать exists()
чтобы проверить, существует ли набор данных в той же таблице, что и BigQuery.