问题描述
我正在尝试为其他数据科学家和数据分析师构建我们内部工具的参考实现,用于 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'],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,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 系统不太熟悉,我相信我的困惑可能是由于概念错误,但我很乐意了解更多信息 :)
解决方法
您的代码在 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,## 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 如果它们不够用,你应该去获取秘密。
也确实使用双&符号,例如。 &&
而不是 &
,后者是 vectorized AND 运算符。此处您应该只有一个值,如果情况并非如此,您将欢迎发出警告。