Не применимый метод для st_write, примененный к объекту класса "c ('tbl_df', 'tbl', 'data.frame')" - PullRequest
0 голосов
/ 31 мая 2018

Я пытаюсь перенести данные из Thingspeak API в базу данных postgres.API ограничивает каждый запрос 8000 наблюдениями, но мне нужно потянуть миллионы!Я использую R для итеративного извлечения из API, провожу споры, а затем отправляю результаты в виде data.frame в мою таблицу в БД.

Текущий способ, которым я это делаю, основан на функции dbWriteTable() из пакета RPostgres.Однако этот метод не учитывает существующие наблюдения в БД.Я должен вручную DELETE FROM table_name перед запуском скрипта, иначе я буду писать дубликаты наблюдений каждый раз, когда пытаюсь обновить базу данных.Я все еще трачу время на переписывание удаленных наблюдений, и из-за этого сценарий занимает ~ 2 дня.

Я бы предпочел скрипт, который включает в себя функциональность предложения postgres-9.5 'ON CONLFICT DO NOTHING, поэтому мне не нужно тратить время на повторную загрузку наблюдений, которые уже находятся в БД,Я обнаружил, что функции st_write() и st-read() из пакетов sf полезны для запуска SQL-запросов непосредственно из R, но они наткнулись на препятствие.В настоящее время я застрял, пытаясь загрузить 8000 наблюдений в каждом df из R в мой db.Я получаю следующую ошибку:

Подключение к базе данных:

# db, host, port, pw, and user are all objects in my R environment
con <- dbConnect(drv = RPostgres::Postgres()
             ,dbname = db
             ,host = host
             ,port = port
             ,password = pw
             ,user = user)

Текущий подход с использованием RPostgres:

dbWriteTable(con
    ,"table_name" 
    ,df 
    ,append = TRUE
    ,row.names = FALSE)

Новый подход с использованием sf:

st_write(conn = conn
      ,obj = df
      ,table = 'table_name'
      ,query = "INSERT INTO table_name ON CONFLICT DO NOTHING;"
      ,drop_table = FALSE
      ,try_drop = FALSE
      ,debug = TRUE)

Сообщение об ошибке:

Error in UseMethod("st_write") : 
  no applicable method for 'st_write' applied to an object of class "c('tbl_df', 'tbl', 'data.frame')"

Редактировать:

Преобразование в строго кадр данных, то есть df <- as.data.frame(df) или attributes(df)$class <- "data.frame", привело к аналогичному сообщению об ошибке,только без tbl_df или tbl классов.

Самый последний подход с sf:

Я добился определенного прогресса в использовании st_write(), изменив следующее:

# convert geom from WKT to feature class
df$geom <- st_as_sfc(df$geom)

# convert from data.frame to sf class
df <- st_as_sf(df)

# write sf object to db
st_write(dsn = con # changed from drv to dsn argument
    ,geom_name = "geom"
    ,table = "table_name"
    ,query = "INSERT INTO table_name ON CONFLICT DO NOTHING;"
    ,drop_table = FALSE
    ,try_drop = FALSE
    ,debug = TRUE
    )

Новая ошибка:

Error in result_create(conn@ptr, statement) : 
  Failed to fetch row: ERROR:  type "geometry" does not exist at character 345

Я почти уверен, что это потому, что я еще не установил расширение PostGIS в своей базе данных PostgreSQL.Если бы кто-нибудь мог подтвердить, я был бы признателен!Установка PostGIS довольно длительный процесс, поэтому я не смогу предоставить обновление в течение нескольких дней.Я надеюсь, что я решил проблему с функцией st_write(), хотя!

...