【问题标题】:R function decorator for data base connection用于数据库连接的 R 函数装饰器
【发布时间】:2019-09-04 09:50:10
【问题描述】:

我想在 R 中编写函数装饰器来建立数据库连接。我在 R The Weak Learner Decorators in R 中编写了装饰器的基本步骤。这篇文章中的示例工作正常。

要连接到数据库,我必须在装饰器本身内部传递一个参数 data_base_name,这会给我一个错误消息:Error in eval(parse(text = text, keep.source = FALSE), envir) : object 'data_base_name' not found

我的装饰器功能:

    db_connect_decorator<-function(f) {
    function(...) {
        loginfo(str_glue("connecting to {data_base_name}"))
        for(i in 1:5){
        bSuccess=F
        tryCatch({
            con = dbConnect(RMySQL::MySQL(), 
                            user=Sys.getenv("DB_USER"), 
                            password=Sys.getenv("DB_PASSWORD"), 
                            dbname=data_base_name, 
                            host=Sys.getenv("DB_HOST"),
                            port=Sys.getenv("DB_PORT") %>% as.integer())
            bSuccess=T
        }, error = function(e) {
            logerror(str_c("Error connecting data base: ", e, "trying to reconnect", sep = " "))
            Sys.sleep(1)
        })
        if(bSuccess) {
            assert(dbIsValid(con))
            Sys.sleep(1)
            result = f(con, ...)  
            assert(dbDisconnect(con))
            return(result)
        }else{
            logerror("Failed to connect to database")
            return(NULL)
        }
        }
    }
    }

教程中描述的装饰器包装器(无需额外参数即可正常工作):

    `%@%` = function(`@`, f) {
    `@`(f)
    }

使用数据库的函数,包含数据库名称:

    db_download<-db_connect_decorator %@% function(data_base_name, con=NULL){
    db_rs = dbSendQuery(con, "select * from my_table")
    res<<-fetch(db_rs, n=-1)
    dbClearResult(db_rs)
    res    
    }

这段代码给了我错误:

    db_download("mydb")

如何将附加变量传递给 R 中的装饰器函数,或者一些解决方法?

【问题讨论】:

  • 它被标记为python的什么?
  • 我想要python中的装饰器,所以我添加了这个标签。这将有助于找到书面答案

标签: r decorator


【解决方案1】:

我自己找到了答案。这是通用方法,但我将其用于数据库查询示例。

必须在函数调用中将省略号参数转换为Rlist,所有参数都必须命名。这是我的解决方案:

    fdecorator<-function(f, ...) {
        function(...) {
        kargs<-list(...)
        print(kargs$data_base_name)
        tryCatch({
            con= dbConnect(RMySQL::MySQL(),
                        user=Sys.getenv("DB_USER"),
                        password=Sys.getenv("DB_PASSWORD"),
                        dbname=kargs$data_base_name,
                        host=Sys.getenv("DB_HOST"),
                        port=Sys.getenv("DB_PORT") %>% as.integer())
            f(con, ...)
            dbDisconnect(con)
        }, error = function(e) {
            logerror(str_glue("Error connecting data base: {e}"))
        })
        }
    }
    f<-function(con, ...){
        kargs<-list(...)
        print(str_glue("Querying data base {kargs$data_base_name}"))
        # query database
    }
    fdecorated<-fdecorator(f)
    fdecorated(data_base_name="my_db")

【讨论】:

    猜你喜欢
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-27
    • 2019-05-26
    • 2017-11-26
    相关资源
    最近更新 更多