将 dplyr 查询保存到 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() 的东西,但理想情况下,它可以与上面的数据操作管道很好地集成。

解决方法

我使用 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")

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...