在 R6 的初始化中调用 R6 class 的函数

Calling function of an R6 class within the initialize of 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)
      }
    )
    
  )

然而,我似乎无法访问初始化程序中的 get_secrets 函数,这与我的同事在 python 中所做的相反。

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

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

您的代码在 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!

检查你的参数是否丢失(上面我只检查了最后一个,如果你只做位置参数,它会起作用,对此没有保证),或者设置你有意义处理的默认值,或者只是写一个检查输入参数和 returns FALSE 的函数,如果它们不够用,你应该去获取秘密。

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