在 rmarkdown 中的 sql 块中提示连接字符串

Prompt for connection string in sql chunk within rmarkdown

一直在四处寻找,但找不到我正在寻找的答案。我试图找到一种方法来提示用户输入数据库连接用户名,因为当我 运行 knitr.

时 readlines 不工作

我试过的;

正如@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/.

    中描述的其他技巧来处理。