将 dplyr 查询保存到 dbplyr 中的不同模式

Save dplyr query to different schema in dbplyr

我有一个 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() 的东西,但理想情况下它可以与上面的数据处理管道很好地集成。

我使用 DBI 包中的 dbExecute 执行此操作。

关键思想是提取定义当前远程 table 的查询,并将其作为写入 table 的更大 SQL 查询中的子查询。这需要 (1) 模式存在,(2) 您有权编写新的 tables,以及 (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 服务器中写入新的 table 的子句(我使用的是 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")