У меня есть столбец, содержащий json строк в таблице на PostgreSQL БД.
Я хочу удалить его на стороне сервера, и я смогвыяснить код SQL, чтобы сделать это.Проблема, с которой я сталкиваюсь, заключается в том, что я хотел бы иметь возможность вставить эту операцию в dbplyr
цепочку каналов, то есть обновить объект tbl_lazy
и еще не выполнить запрос, и я не понимаю внутренности *Для этого достаточно 1009 * dbplyr .
См. Пример ниже:
Настройка
library("RPostgres")
library("dplyr")
drv <- RPostgres::dbDriver("Postgres")
#### NOT REPRODUCIBLE!!! ####
con <- RPostgres::dbConnect(drv, dbname = mydbname, sslmode = 'require',
host = myhost, port = 5432,
user = user, password = mypassword)
#############################
my_tbl <- tribble(~a, ~bcd,
1, '{"b": "foo1", "c": "bar1", "d": "baz1"}',
2, '{"b": "foo2", "c": "bar2", "d": "baz2"}')
copy_to(con, my_tbl, "my_tbl",
temporary = TRUE)
Частичное решение (нетленивая оценка)
unnest_json <-function(data, json_col, ...){
# build character vector whose names are cols to be created and values columns
# to be extracted
dots <- sapply(as.list(substitute(list(...)))[-1], as.character)
json_col <- as.character(substitute(json_col))
# json extraction string
query0 <- sprintf("%s::json->'%s' as %s",json_col, dots, names(dots))
# complete query
query <- sprintf("SELECT *, %s FROM (%s) AS PREV",
paste(query0, collapse = ", "),
dbplyr::sql_render(data))
# fetch (when I'd rather update the tbl_lazy object instead)
dbGetQuery(data$src$con, query)
}
con %>%
tbl("my_tbl") %>%
unnest_json(bcd, unnested_b = "b", unnested_c = "c")
# a bcd unnested_b unnested_c
# 1 1 {"b": "foo1", "c": "bar1", "d": "baz1"} "foo1" "bar1"
# 2 2 {"b": "foo2", "c": "bar2", "d": "baz2"} "foo2" "bar2"
Желаемая функция
Я хотел бы иметь возможность сделать, например:
con %>%
tbl("my_tbl") %>%
unnest_json(bcd, unnested_b = "b", unnested_c = "c") %>% # not evaluated at this point
select(-bcd) %>%
head(1) %>%
collect()
# a unnested_b unnested_c
# 1 1 "foo1" "bar1"