Сохраните запрос dplyr в другой схеме в dbplyr

#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")