在 rmarkdown 中的 sql 块中提示连接字符串
Prompt for connection string in sql chunk within rmarkdown
一直在四处寻找,但找不到我正在寻找的答案。我试图找到一种方法来提示用户输入数据库连接用户名,因为当我 运行 knitr.
时 readlines 不工作
我试过的;
- 在我的系统环境中设置用户名是可行的,但我宁愿让将重新运行此脚本的用户提示输入他们的用户名。
- 在 yaml 输出中设置参数,但根据我在网上阅读的内容,我仍然在脚本中明确注明我的用户名(不太熟悉使用参数,所以也许我错了)
正如@therog1 所说,呈现 rmarkdown 文档不能有任何用户交互:所有输出都是 sink
'(捕获),并且没有输入是 opened/allowed(显式 [=71 除外) =] 操作)。因此,如果您需要设置连接凭据,则需要在 呈现文档之前确定(并可选地验证)。
要将这些凭据放入 rmarkdown 文档以进行连接,我强烈建议使用参数化文档,正如已经建议的那样。虽然可以不这样做,但最好以 formal/proper 方式进行。 (对我来说,它类似于函数声明:如果您将 Rmd 文件视为一个“函数”,您希望使用特定参数调用该函数,而不是强制它假定存在 variables/data 等。在 rmarkdown
-说话,“函数参数”是文档的params=
。)
有几种方法可以解决这个问题;对我来说最突出的两个是:
如果在RStudio中,按照therog1的建议,可以使用params="ask"
,RStudio应该会问你参数;如果用户在 RStudio 界面中选择“使用参数编织”,这也适用。如果任何用户不使用 RStudio,此方法将不起作用。
例如,这里有一个 Rmd 启动这个:
---
title: hello world
params:
dbuser:
label: "Username"
value: ""
input: text
dbpass:
label: "Password"
value: ""
input: password
---
```{r echo = FALSE}
con <- DBI::dbConnect(...) # using params$dbuser and params$dbpass
```
当用户选择 “使用参数编织” 时,他们会看到
(https://bookdown.org/yihui/rmarkdown/params-knit.html and https://rmarkdown.rstudio.com/lesson-6.html 都是很好的参考资料。)
另一种方法(在 RStudio 以及其他 interactive R 接口中,包括可怕的 Rterm)是使用 keyring
包( CRAN, website, github)。一个好处是,一旦设置,用户永远不必为此报告输入用户名或密码,并且凭据 安全地 存储在 OS 特定的加密保险库中。
---
title: hello world
params:
dbservice: companydb
dbuser: null
dbpass: null
---
```{r echo = FALSE}
dbuser <-
if (is.null(params$dbuser)) {
keyring::key_list(params$dbservice)$username[1] # arbitrarily pick the first if multiple found
} else params$dbuser
stopifnot(length(dbuser), !is.na(dbuser))
dbpass <-
if (is.null(params$dbpass)) {
keyring::key_get(params$dbservice, dbuser)
} else params$dbuser
con <- DBI::dbConnect(...) # using dbuser and dbpass
```
如果 OS 凭据保险库不是立即可用的,OS 可能会提示用户输入他们的 OS 密码(不是数据库密码)以验证保险库可以通过R代码访问。在 windows 这不是必需的,我没有在 macos/linux.
上测试过
每位用户的一次性设置为:
# install.packages("keyring") # if necessary
keyring::key_set("companydb", "theirusername")
并且将提示用户(通过 GUI 弹出窗口 window)输入安全(隐藏的)密码。这存储在 OS keyring/credentials 保险库中。这里的字符串 "companydb"
是 完全任意的 ,但必须是您同意(或强制)用户的“已知”事物。为了方便您,它需要对所有用户都相同。 (精明的用户可以使用 rmarkdown::render("path/to/doc.Rmd", params=list(dbservice="otherservicename"))
手动覆盖它,尽管这似乎几乎没有必要。)数据库永远不会看到它,因此它可以而且可以说应该是可读和明确的(即,特定于特定的 database/environment) . (它应该是唯一的,这样它就不会无意中覆盖用户对 OS 凭据库的其他使用。)
如果任何用户将在 非 交互式环境中呈现文档(因此不能保证凭据保险库可用),那么这可能无法工作 -是。但是,这些情况通常可以使用环境变量或 https://db.rstudio.com/best-practices/managing-credentials/.
中描述的其他技巧来处理。
一直在四处寻找,但找不到我正在寻找的答案。我试图找到一种方法来提示用户输入数据库连接用户名,因为当我 运行 knitr.
时 readlines 不工作我试过的;
- 在我的系统环境中设置用户名是可行的,但我宁愿让将重新运行此脚本的用户提示输入他们的用户名。
- 在 yaml 输出中设置参数,但根据我在网上阅读的内容,我仍然在脚本中明确注明我的用户名(不太熟悉使用参数,所以也许我错了)
正如@therog1 所说,呈现 rmarkdown 文档不能有任何用户交互:所有输出都是 sink
'(捕获),并且没有输入是 opened/allowed(显式 [=71 除外) =] 操作)。因此,如果您需要设置连接凭据,则需要在 呈现文档之前确定(并可选地验证)。
要将这些凭据放入 rmarkdown 文档以进行连接,我强烈建议使用参数化文档,正如已经建议的那样。虽然可以不这样做,但最好以 formal/proper 方式进行。 (对我来说,它类似于函数声明:如果您将 Rmd 文件视为一个“函数”,您希望使用特定参数调用该函数,而不是强制它假定存在 variables/data 等。在 rmarkdown
-说话,“函数参数”是文档的params=
。)
有几种方法可以解决这个问题;对我来说最突出的两个是:
如果在RStudio中,按照therog1的建议,可以使用
params="ask"
,RStudio应该会问你参数;如果用户在 RStudio 界面中选择“使用参数编织”,这也适用。如果任何用户不使用 RStudio,此方法将不起作用。例如,这里有一个 Rmd 启动这个:
--- title: hello world params: dbuser: label: "Username" value: "" input: text dbpass: label: "Password" value: "" input: password --- ```{r echo = FALSE} con <- DBI::dbConnect(...) # using params$dbuser and params$dbpass ```
当用户选择 “使用参数编织” 时,他们会看到
(https://bookdown.org/yihui/rmarkdown/params-knit.html and https://rmarkdown.rstudio.com/lesson-6.html 都是很好的参考资料。)
另一种方法(在 RStudio 以及其他 interactive R 接口中,包括可怕的 Rterm)是使用
keyring
包( CRAN, website, github)。一个好处是,一旦设置,用户永远不必为此报告输入用户名或密码,并且凭据 安全地 存储在 OS 特定的加密保险库中。--- title: hello world params: dbservice: companydb dbuser: null dbpass: null --- ```{r echo = FALSE} dbuser <- if (is.null(params$dbuser)) { keyring::key_list(params$dbservice)$username[1] # arbitrarily pick the first if multiple found } else params$dbuser stopifnot(length(dbuser), !is.na(dbuser)) dbpass <- if (is.null(params$dbpass)) { keyring::key_get(params$dbservice, dbuser) } else params$dbuser con <- DBI::dbConnect(...) # using dbuser and dbpass ```
如果 OS 凭据保险库不是立即可用的,OS 可能会提示用户输入他们的 OS 密码(不是数据库密码)以验证保险库可以通过R代码访问。在 windows 这不是必需的,我没有在 macos/linux.
上测试过每位用户的一次性设置为:
# install.packages("keyring") # if necessary keyring::key_set("companydb", "theirusername")
并且将提示用户(通过 GUI 弹出窗口 window)输入安全(隐藏的)密码。这存储在 OS keyring/credentials 保险库中。这里的字符串
"companydb"
是 完全任意的 ,但必须是您同意(或强制)用户的“已知”事物。为了方便您,它需要对所有用户都相同。 (精明的用户可以使用rmarkdown::render("path/to/doc.Rmd", params=list(dbservice="otherservicename"))
手动覆盖它,尽管这似乎几乎没有必要。)数据库永远不会看到它,因此它可以而且可以说应该是可读和明确的(即,特定于特定的 database/environment) . (它应该是唯一的,这样它就不会无意中覆盖用户对 OS 凭据库的其他使用。)如果任何用户将在 非 交互式环境中呈现文档(因此不能保证凭据保险库可用),那么这可能无法工作 -是。但是,这些情况通常可以使用环境变量或 https://db.rstudio.com/best-practices/managing-credentials/.
中描述的其他技巧来处理。