BigQuery Python API: сохранение пустых полей во время задания extract_table - PullRequest
0 голосов
/ 25 мая 2018

У меня есть следующий код:

job_config = bigquery.ExtractJobConfig()
job_config.compression = bigquery.Compression.GZIP
job_config.destination_format = (
    bigquery.DestinationFormat.NEWLINE_DELIMITED_JSON)

destination_uri = 'gs://{}/{}'.format(bucket_name, gcs_filename)

extract_job = client.extract_table(
    table,
    destination_uri,
    job_config=job_config,
    location='US')  # API request
extract_job.result()  # Waits for job to complete.

(Обратите внимание, что я получаю свой объект таблицы в другом месте.)

Это работает и выгружает запрошенную таблицу в GCS как newline-JSON с разделителямиОднако некоторые столбцы в таблице могут иметь значение NULL, а некоторые содержат нулевые значения.В интересах обеспечения согласованности всех наших данных я хотел бы сохранить нулевые значения в результатах json.Есть ли способ сделать это без необходимости использовать avro?

Этот пост здесь: Большой извлечение таблицы запросов в JSON, сохранение нулей? ... предлагает на самом деле запросить таблицу.Я не думаю, что это вариант для меня, так как таблицы, которые я извлекаю, содержат миллионы строк в каждой.Один, на который я смотрю, содержит почти 100 миллионов строк и весит более 25 ГБ данных.Но мне не удалось найти способ настроить задание извлечения для сохранения нулей.

Ответы [ 2 ]

0 голосов
/ 11 июля 2018

Этот аргумент был приведен ранее в SO.Я предлагаю вам просмотреть этот пост , включая объяснения и обходные пути для вашей проблемы.

Есть несколько хороших ответов, например, от Mosha (Google Software Engineer):

Это стандартное поведение NULL в SQL и во всех базах данных SQL (OracleMicrosoft SQL Server, PostgreSQL, MySQL и т. Д.) Работают точно так же.Если проверка IS NULL слишком утомительна, альтернативным решением является использование функции IFNULL или COALESCE для преобразования NULL в ненулевое значение, то есть

select * from
(select NULL as some_nullable_col, "name1" as name),
(select 4 as some_nullable_col, "name2" as name),
(select 1 as some_nullable_col, "name3" as name),
(select 7 as some_nullable_col, "name4" as name),
(select 3 as some_nullable_col, "name5" as name)
WHERE ifnull(some_nullable_col,0) != 3
0 голосов
/ 26 мая 2018

Я думаю, что лучший способ сделать это - сначала использовать задание запроса.

  1. Вы получили таблицу для извлечения откуда-то и запускаете задание запроса
  2. Запустите извлечение как CSV без заголовков

Существует код, который делает это

job_config = bigquery.QueryJobConfig()
gcs_filename = 'file_with_nulls*.json.gzip'

table_ref = client.dataset(dataset_id).table('my_null_table')
job_config.destination = table_ref

job_config.write_disposition = bigquery.WriteDisposition.WRITE_TRUNCATE

# Start the query, passing in the extra configuration.
query_job = client.query(
    """#standardSql
    select TO_JSON_STRING(t) AS json from `project.dataset.table` as t ;""",
    location='US',
    job_config=job_config)

while not query_job.done():
    time.sleep(1)

#check if table successfully written
print("query completed")
job_config = bigquery.ExtractJobConfig()
job_config.compression = bigquery.Compression.GZIP
job_config.destination_format = (
    bigquery.DestinationFormat.CSV)
job_config.print_header = False

destination_uri = 'gs://{}/{}'.format(bucket_name, gcs_filename)

extract_job = client.extract_table(
    table_ref,
    destination_uri,
    job_config=job_config,
    location='US')  # API request
extract_job.result()
print("extract completed")

После того, как все сделано - вы можете удалить временную таблицу, созданную на шаге 1. Стоимость будет очень низкой, если вы сделаете это быстро (1 ТБхранилище за месяц стоит 20 $ - значит, для 25 ГБ даже на 1 час это будет 20/30/24 = 3 цента)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...