Google BigQuery: в Python добавление столбцов делает все остальные столбцы обнуляемыми. - PullRequest
0 голосов
/ 19 июня 2020

У меня уже существует таблица со следующей схемой:

{
  "schema": {
    "fields": [
      {
        "mode": "required",
        "name": "full_name",
        "type": "string"
      },
      {
        "mode": "required",
        "name": "age",
        "type": "integer"
      }]
  }
}

Она уже содержит такие записи, как:

{'full_name': 'John Doe',
          'age': int(33)}

Я хочу вставить новую запись с новым полем и задание загрузки автоматически добавляет новый столбец по мере загрузки. Новый формат выглядит так:

record = {'full_name': 'Karen Walker',
          'age': int(48),
          'zipcode': '63021'}

Мой код выглядит следующим образом:

from google.cloud import bigquery
client = bigquery.Client(project=projectname)
table = client.get_table(table_id)

config = bigquery.LoadJobConfig()
config.autoedetect = True
config.source_format = bigquery.SourceFormat.NEWLINE_DELIMITED_JSON
config.write_disposition = bigquery.WriteDisposition.WRITE_APPEND
config.schema_update_options = [
    bigquery.SchemaUpdateOption.ALLOW_FIELD_ADDITION,
                               ]

job = client.load_table_from_json([record], table, job_config=config)
job.result()

Это приводит к следующей ошибке:

400 Предоставленная схема не соответствует таблице my_project: my_dataset: mytable. Возраст поля изменил режим с REQUIRED на NULLABLE

Я могу исправить это, изменив config.schema_update_options следующим образом:

    bigquery.SchemaUpdateOption.ALLOW_FIELD_ADDITION,
    bigquery.SchemaUpdateOption.ALLOW_FIELD_RELAXATION
                               ]

Это позволяет мне вставить новую запись с помощью zipcode добавлен в схему, но в результате оба full_name и age становятся NULLABLE, что мне не подходит. Есть ли способ предотвратить автоматическое определение схемы при изменении существующих столбцов?

1 Ответ

1 голос
/ 22 июня 2020

Если вам нужно добавить поля в вашу схему, вы можете сделать следующее:

from google.cloud import bigquery
client = bigquery.Client()

table = client.get_table("your-project.your-dataset.your-table")

original_schema = table.schema   # Get your current table's schema
new_schema = original_schema[:]  # Creates a copy of the schema.
# Add new field to schema
new_schema.append(bigquery.SchemaField("new_field", "STRING")) 

# Set new schema in your table object
table.schema = new_schema   
# Call API to update your table with the new schema
table = client.update_table(table, ["schema"])  

После обновления схемы вашей таблицы вы можете загрузить свои новые записи с этим дополнительным полем, игнорируя любые конфигурации схемы.

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