#r #dplyr #rjava #dbplyr #rjdbc
Вопрос:
У меня есть соединение JDBC, и я хотел бы запросить данные из одной схемы и сохранить их в другой
library(tidyverse)
library(dbplyr)
library(rJava)
library(RJDBC)
# access the temp table in the native schema
tbl(conn, "temp")
temp_ed <- temp %*% mutate(new = 1)
# I would like to save temp_ed to a new schema "schmema_new"
Я хотел бы использовать что-то вроде dbplyr::compute()
, но конкретно определить схему вывода. Кажется dbplyr::copy_to
, это можно использовать, но потребуется перенести данные через локальную машину.
Я хочу использовать что-то вроде RJDBC::dbSendUpdate()
, но которое идеально интегрировалось бы с конвейером обработки данных выше.
Ответ №1:
Я делаю это с помощью dbExecute
DBI
пакета.
Ключевая идея состоит в том, чтобы извлечь запрос, определяющий текущую удаленную таблицу, и сделать его подзапросом в более крупном SQL — запросе, который записывает таблицу. Для этого требуется, чтобы (1) схема существовала, (2) у вас было разрешение на написание новых таблиц и (3) вы знали правильный синтаксис SQL.
Выполнение этого напрямую может выглядеть так:
tbl(conn, "temp")
temp_ed <- temp %*% mutate(new = 1)
save_table_query = paste(
"SELECT * INTO my_database.schema_new.my_table FROM (n",
dbplyr::sql_render(temp_ed),
"n) AS sub_query"
)
dbExecute(conn, as.character(save_table_query))
INTO
это предложение для написания новой таблицы в SQL server (тип SQL, который я использую). Вам нужно будет найти эквивалентное предложение для вашей базы данных.
На практике я использую пользовательскую функцию, которая выглядит примерно так:
write_to_database <- function(input_tbl, db, schema, tbl_name){
# connection
tbl_connection <- input_tbl$src$con
# SQL query
sql_query <- glue::glue(
"SELECT *n",
"INTO {db}.{schema}.{tbl_name}n",
"FROM (n",
dbplyr::sql_render(input_tbl),
"n) AS sub_query"
)
result <- dbExecute(tbl_connection, as.character(sql_query))
}
Применяя это в своем контексте:
tbl(conn, "temp")
temp_ed <- temp %*% mutate(new = 1)
write_to_database(temp_ed, "my_database", "schema_new", "my_table")