如何使用 R & RMySQL 连接到函数外部的数据库,在函数内部断开连接,然后在该函数内部重新连接

Jon*_*ton 1 database-connection r function scoping rmysql

我有一个利用连接到 Amazon RDS 的 RMySQL 库的 R 脚本。该脚本最初会在运行该函数之前连接到 RDS。在函数内部,查询RDS上的MySQL,然后执行Sys.sleep命令,持续24小时(86400秒),然后恢复。因为 Amazon 的 RDS wait_timeout 参数设置为 8 小时 (28800),这会导致我的 R 控制台中出现此错误:

Error in .local(conn, statement, ...) :
    could not run statement: MySQL server has gone away
Run Code Online (Sandbox Code Playgroud)

我不能这样做,所以我尝试了以下代码:

duration <- 86400
con <- dbConnect(MySQL(),
       user = passwordFile$user[1],
       password = passwordFile$password[1],
       host = passwordFile$host[1],
       dbname = passwordFile$dbname[1])
query <- function(...) dbGetQuery(con, ...)
testing <- function(){
       test1 <- query("SELECT * FROM a_log")
       print(test1)
       dbDisconnect(con)
       Sys.sleep(duration)
       con <- dbConnect(MySQL(),
              user = passwordFile$user[1],
              password = passwordFile$password[1],
              host = passwordFile$host[1],
              dbname = passwordFile$dbname[1])
       test2 <- query("SELECT * FROM a_log")
       return(test2)
}
temp <- testing()
print(temp)
Run Code Online (Sandbox Code Playgroud)

test1 对象打印良好。但是,在尝试打印 test2 时,出现以下错误(即使我将持续时间设置为 1):

>Error in mysqlQuickSQL(conn, statement, ...) : expired MySQLConnection
Run Code Online (Sandbox Code Playgroud)

是否可以在函数外部连接到 MySQL server.database,然后在函数内断开连接,然后在函数内重新连接?谢谢你!!

Nat*_*rth 5

如果无法实际尝试此代码,一个可能的问题是您有两个函数试图管理一个连接。它可以帮助将任务与函数分开:connect_to_amazon创建连接、query返回表并testing包装进程。

在父环境中拥有函数引用值也是有风险的,因为这些值以后可能会更改甚至不存在。

您可以使用query或任何其他访问 Amazon 数据库的函数connect_to_amazon来建立连接,然后on.exit确保该函数完成后将其关闭。

connect_to_amazon <- function(password_file) {
  dbConnect(
    MySQL(),
    user     = password_file$user[1],
    password = password_file$password[1],
    host     = password_file$host[1],
    dbname   = password_file$dbname[1]
  )
}

query <- function(..., password_file) {
  amazon_con <- connect_to_amazon(password_file)
  on.exit(dbDisconnect(amazon_con), add = TRUE)
  dbGetQuery(conn = amazon_con, ...)
}

testing <- function(password_file) {
  test1 <- query("SELECT * FROM a_log", password_file = password_file)
  print(test)
  Sys.sleep(duration)
  test2 <- query("SELECT * FROM a_log", password_file = password_file)
  return(test2)
}
Run Code Online (Sandbox Code Playgroud)

如果您需要使用 Amazon 数据库执行任何其他任务,您可以编写另一个包装函数(例如write_amazon_table(..., password_file)),或者connect_to_amazon直接调用并使用连接。