首页 > 解决方案 > 在 R6 的初始化中调用 R6 类的函数

问题描述

我正在尝试为其他数据科学家和数据分析师在 R 中为数据库连接样板编码构建我们的内部工具的参考实现

我们的软件开发人员在 python 中做了类似的事情:

class DataRepository:

    def __init__(self):
        if user is not None and account is not None and password is not None and warehouse is not None and role is not None and database is not None and schema is not None:
            self.ctx = snowflake.connector.connect(
                user=user,
                password=password,
                account=account,
                role=role,
                database=database,
                schema=schema,
                warehouse=warehouse,
                login_timeout=login_timeout,
                ocsp_fail_open=ocsp_fail_open
            )
        else:
            secret_str = self.get_secrets()

            self.ctx = snowflake.connector.connect(
                user=secret_str['user'],
                password=secret_str['password'],
                account=secret_str['account'],
                role=secret_str['role'],
                database=secret_str['database'],
                schema=secret_str['schema'],
                warehouse=secret_str['warehouse'],
                login_timeout=login_timeout,
                ocsp_fail_open=ocsp_fail_open
            )

    def get_secrets(self):
        my_session = boto3.session.Session(region_name=AWS_DEFAULT_REGION)
        client = my_session.client(
            service_name='secretsmanager',
            region_name=AWS_DEFAULT_REGION,
        )
        get_secret_value_response = client.get_secret_value(
            SecretId=SECRET_NAME
        )
        secret_str = json.loads(get_secret_value_response['SecretString'])
        return secret_str

我试图用 S3 重现这个:

DataRepository <-
  R6Class(
    classname = "DataRepository",
    public = list(
      ctx = NULL,
      secrets = NULL,
      initialize = function() {
        if (length(user) == 1 &
            length(account) == 1 & length(password) == 1
            &
            length(warehouse) == 1 &
            length(role) == 1 & length(database) == 1) {
          self$ctx <- dbConnect(
            odbc::odbc(),
            Driver = "SnowflakeDSIIDriver",
            Database = database,
            Uid = user,
            Pwd = password,
            Server = paste0(account, ".snowflakecomputing.com"),
            role = role
          )
        } else {
          secret_dict <- self$getSecrets()
          self$ctx <- dbConnect(
            odbc::odbc(),
            Driver = secret_dict$user,
            Database = secret_dict$database,
            Uid = secret_dict$user,
            Pwd = secret_dict$password,
            Server = paste0(secret_dict$account, ".snowflakecomputing.com"),
            role = secret_dict$account
          )
        }
      },
      getSecrets = function() {
        secrets_client <- paws::secretsmanager(config =
                                                 list(region = AWS_REGION))
        get_secret_value_response <- secrets_client$get_secret_value(SecretId = SECRETS_NAME)
        secrets_str <-
          get_secret_value_response$SecretString %>% fromJSON()
        return(secrets_str)
      }
    )
    
  )

但是,我似乎无法像我的同事在 python 中那样访问初始化程序中的 get_secrets 函数。

有什么简单的解决方案吗?

PS:我对 R6 系统不太熟悉,我相信我的困惑可能是由于概念上的错误,但我很乐意了解更多信息 :)

标签: pythonroopr6

解决方案


您的代码在 getSecrets 方面很好,但是您忘记定义构造函数参数。

考虑一下:


DataRepository <-
  R6Class(
    classname = "DataRepository",
    public = list(
      ctx = NULL,
      secrets = NULL,
      initialize = function(user, account,password,warehouse,role,database) {
        if ( !missing(database) &&
            length(user) == 1 &&
            length(account) == 1 && length(password) == 1 &&
            length(warehouse) == 1 &&
            length(role) == 1 && length(database) == 1) {
          self$ctx <- dbConnect(
            odbc::odbc(),
            Driver = "SnowflakeDSIIDriver",
            Database = database,
            Uid = user,
            Pwd = password,
            Server = paste0(account, ".snowflakecomputing.com"),
            role = role
          )
        } else {
          secret_dict <- self$getSecrets()
          ## self$ctx <- dbConnect(
          ##   odbc::odbc(),
          ##   Driver = secret_dict$user,
          ##   Database = secret_dict$database,
          ##   Uid = secret_dict$user,
          ##   Pwd = secret_dict$password,
          ##   Server = paste0(secret_dict$account, ".snowflakecomputing.com"),
          ##   role = secret_dict$account
          ## )
        }
      },
      getSecrets = function() {
        cat( "I am in the getSecrets method!\n")
        ## secrets_client <- paws::secretsmanager(config =
        ##                                          list(region = AWS_REGION))
        ## get_secret_value_response <- secrets_client$get_secret_value(SecretId = SECRETS_NAME)
        ## secrets_str <-
        ##   get_secret_value_response$SecretString %>% fromJSON()
        ## return(secrets_str)
      }
    )
  )

dr = DataRepository$new()

输出:


> dr = DataRepository$new()
I am in the getSecrets method!

检查你的参数是否丢失(上面我只检查了最后一个参数,如果你只做位置参数,这是没有保证的),或者设置你有意义地处理的默认值,或者只是编写一个检查输入参数的函数如果它们还不够,则返回 FALSE,而您应该去获取秘密。

也请使用双与号,例如。&&而 not &,后者是向量化的AND 运算符。您在这里应该只有一个值,如果不是这种情况,您会欢迎警告。


推荐阅读