R Shiny破坏了使用.pgpass的PostgreSQL身份验证

3

我已将数据库密码存储在pgpass.conf文件中。我使用RPostgres从R连接到数据库,没有指定密码,因此它会从pgpass.conf中读取,就像这样:

con <- dbConnect(RPostgres::Postgres(), 
                 dbname = "dbname",
                 user = "username",
                 host = "localhost",
                 port = "5432")

它通常工作得很好,但是当我尝试从闪亮应用程序连接到数据库时,它不起作用。 连接定义与上面完全相同,并放置在server.R脚本中。 当我使用默认参数运行Shiny应用程序时,会出现错误:

FATAL:  password authentication failed for user "username"
password retrieved from file "C:\Users\...\AppData\Roaming/postgresql/pgpass.conf"

当明确在连接定义中给出密码时:

con <- dbConnect(RPostgres::Postgres(), 
                 dbname = "dbname",
                 user = "username",
                 host = "localhost",
                 password = "mypass",
                 port = "5432")

一切都正常。

更加奇怪的是,当端口设置为某个值时(例如:shiny::runApp(port = 4000)),连接会在不指定密码的情况下建立,但仅限于第一次 - 这意味着当应用程序在同一R会话中关闭并重新打开时,错误会再次发生。

我测试了包'RPostgreSQL' - 它也不起作用,只是错误信息不同:

Error in postgresqlNewConnection(drv, ...) : 
  RS-DBI driver: (could not connect postgres@localhost on dbname "dbname")

我使用32位的R,但我已经在64位上进行了测试,结果一样。Shiny应用程序在浏览器(Chrome)和Rstudio Viewer中运行。

以下是我的会话信息:

R version 3.2.2 (2015-08-14)
Platform: i386-w64-mingw32/i386 (32-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

locale:
[1] LC_COLLATE=Polish_Poland.1250  LC_CTYPE=Polish_Poland.1250        LC_MONETARY=Polish_Poland.1250
[4] LC_NUMERIC=C                   LC_TIME=Polish_Poland.1250    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] RPostgres_0.1  DBI_0.3.1.9008 shiny_0.12.2  

loaded via a namespace (and not attached):
[1] R6_2.1.1         htmltools_0.2.6  tools_3.2.2      rstudioapi_0.3.1     Rcpp_0.12.1.3    jsonlite_0.9.17  digest_0.6.8    
[8] xtable_1.7-4     httpuv_1.3.3     mime_0.4         RPostgreSQL_0.4
2个回答

2

在Shiny和您的系统R GUI之间,运行命令的环境可能有所不同。我通过将我的凭据存储在Renviron文件中来解决此问题:

readRenviron("~/.Renviron")
con <- dbConnect(RPostgres::Postgres(), 
                 dbname = Sys.getenv('pg_db'),
                 user = Sys.getenv('api_user'),
                 ...)

一个有用的技巧是为staging和production环境分别维护独立的Renvirons,这允许你的脚本使用commandArgs()指定应该使用哪个DB凭据:

#!/usr/bin/env Rscript
environ_path <- switch(commandArgs(),
                  'staging' = {"~/staging.Renviron"},
                  'production' = {"~/production/Renviron"})

readRenviron(environ_path)

然后从BASH终端:

Rscript analysis.R staging

这确实是解决我的问题的可行而简单的方案。 无论如何,我仍然很好奇为什么标准的 pgpass 文件在 Shiny 中不能正常工作。我已经试图在Shiny(实际上是 httpuv)和 psql 的源文件中找到一些东西,但我不擅长 C,所以什么都没有找到。 - BartekCh

0

错误出现在Postgresql中:

C:\Users\...\AppData\Roaming/postgresql/pgpass.conf

文件路径包含"/"而不是"\\"


现代Windows通常可以在文件路径中交替使用\和/(请参见此问题)。 - Brits

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接