Bigrquery принудительно приводит строки к целым числам (схема — это строка)

Я работаю с почтовыми индексами, которые, конечно, имеют ведущие нули. Я правильно загружаю свой фрейм данных, чтобы сохранить ведущие нули в R, но шаг загрузки, похоже, не удался. Вот что я имею в виду:

Вот мой минимальный файл .csv:

zip,val
07030,10
10001,100
90210,1000
60602,10000

Вот код Р

require("bigrquery")
filename <- "minimal.csv"
tablename <- "as_STRING"
ds <- bq_dataset(project='myproject', dataset="zips")

Я также правильно устанавливаю тип в своей схеме, чтобы ожидать их в виде строк.

# first pass
df <- read.csv(filename, stringsAsFactors=F)
# > df
#     zip   val
# 1  7030    10
# 2 10001   100
# 3 90210  1000
# 4 60602 10000

# uh oh!  Let's fix it!

cols <- unlist(lapply(df, class))
cols[[1]] <- "character" # make zipcode a character

# then reload
df2 <- read.csv(filename, stringsAsFactors=F, colClasses=cols)
# > df2
#     zip   val
# 1 07030    10
# 2 10001   100
# 3 90210  1000
# 4 60602 10000

# much better!  You can see my zips are now strings.

Однако, когда я пытаюсь загрузить строки, интерфейс bigrquery жалуется, что я загружаю целые числа, а это не так. Вот схема, ожидающая строки:

# create schema
bq_table_create(bq_table(ds, tablename), fields=df2) # using df2, which has strings

# now prove it got the strings right:
    > bq_table_meta(bq_table(ds, tablename))$schema$fields
    [[1]]
    [[1]]$name
    [1] "zip"

    [[1]]$type
    [1] "STRING"                # GOOD, ZIP IS A STRING!

    [[1]]$mode
    [1] "NULLABLE"


    [[2]]
    [[2]]$name
    [1] "val"

    [[2]]$type
    [1] "INTEGER"

    [[2]]$mode
    [1] "NULLABLE"

Теперь пришло время загрузить....

bq_table_upload(bq_table(ds, tablename), df2) # using df2, with STRINGS
Error: Invalid schema update. Field zip has changed type from STRING to INTEGER [invalid]

Хм? Что это за недопустимое обновление схемы и как я могу остановить его от попыток изменить мои строки, которые содержат данные и схема, на целые числа, которых нет в моих данных и которых нет в схеме?

Происходит ли сериализация javascript, которая возвращает мои строки к целым числам?


person Mittenchops    schedule 23.11.2018    source источник


Ответы (2)


Это связано с тем, что BigQuery автоматически определяет схему, если она не указана. Это можно решить, указав аргумент fields, например так (см. этот аналогичный вопрос Больше подробностей):

bq_table_upload(bq_table(ds, tablename), df2,fields = list(bq_field("zip", "string"),bq_field("val", "integer")))

ОБНОВЛЕНИЕ:

Изучая код,bq_table_upload вызывает bq_perform_upload, что требует аргумент fields в качестве схемы. В конце он анализирует файл data frame как JSON, чтобы загрузить его в BigQuery.

person enle lin    schedule 23.11.2018
comment
Спасибо. Это полезный ответ. Это также очень странно для пакета, почему интерфейс по умолчанию автоматически определяет, а не использует типы данных, заданные фреймом данных? - person Mittenchops; 23.11.2018
comment
@Mittenchops Я добавил в свой ответ еще несколько деталей кода. Я мог бы сказать, что самый простой способ — передать функции аргумент fields, но вы можете отредактировать код для своего варианта использования. - person enle lin; 25.11.2018

Просто изменить:

bq_table_upload(tab, df)

to

bq_table_upload(tab, df, fields=df)

работает.

person Mittenchops    schedule 25.11.2018
comment
Оно делает! Благодарю вас! - person Björn Backgård; 18.04.2019