如何在R语言R6类中集成数据库连接并解决锁定环境报错
报错原因
- R6类实例环境默认处于锁定状态,不允许动态添加未预先声明的字段。你已经将
db_server定义为私有字段,但在initialize方法中使用self$db_server <-赋值,self仅用于访问公有成员,该操作等价于试图给公有环境新增未声明的db_server字段,因此触发锁环境报错。 - 你在
zp_id方法中调用self$db_server也无法正确获取连接,私有成员必须通过private$关键字访问。 - 额外注意:你的代码中调用了
self$zaehlpunkt,但公有字段列表中未预先声明zaehlpunkt,后续运行也会触发找不到字段的错误。
修复方法
方法1:调整字段访问方式(推荐)
按成员归属正确使用self和private,预定义所有用到的字段,修复后的完整代码如下:
LastProfilZdb <- R6Class( classname = "LastProfilZdb", public = list( name = NULL, zp = NULL, data = NULL, # 补充声明用到的zaehlpunkt字段 zaehlpunkt = NULL, zp_id = function() { pool::poolWithTransaction(private$db_server, function(conn){ # 建议改用参数化查询避免SQL注入风险,替代直接字符串拼接 DBI::dbGetQuery(conn, "SELECT ZP_ID FROM ZP_ID WHERE LP_ZP = ? OR ZP_NAME_SAP = ?", params = list(self$zaehlpunkt, self$zaehlpunkt) ) }) }, initialize = function(){ message("Init Data Base Connection") # 私有字段用private$赋值 private$db_server <- pool::dbPool(drv = odbc::odbc(), dsn = "Oracle", schema = "schema" ) }, finalize = function() { message("Closing Data Base Connection") pool::poolClose(private$db_server) } ), private = list( db_server = NULL ) )
方法2:关闭实例环境锁定(不推荐)
如果确实需要动态添加字段,可在定义R6类时添加lock_objects = FALSE参数关闭环境锁定,但该方式会丢失字段预校验能力,不符合R6类的最佳实践:
LastProfilZdb <- R6Class( classname = "LastProfilZdb", lock_objects = FALSE, # 其余原有代码保持不变 ... )
内容的提问来源于stack exchange,提问作者Christoph Macho
相关产品推荐
相关产品推荐

