我正试图使用sql模式通过Emacs连接到PostgreSQL数据库。我启动Emacs,命令M-x sql-postgres
,它会提示用户,数据库和服务器,但不用于密码。空缓冲区打开无论我写什么,我都会得到:
the Password for user james:
psql: FATAL: password authentication failed for user "james"
不过,我可以使用psql登录。我在Linux Antergos中运行GNU Emacs 24.4.1,PostgreSQL版本为9.3.5。
谢谢。。
如果有人来找我,我在sql-postgres命令完成后,通过调用send-invisible并键入我的密码来解决这个问题。Emacs版本24.5.1。
- 启动postgres连接
- 在空白屏幕M-x发送不可见
- 键入密码
- 利润
这里有一个更简单的解决方案,利用了可以在连接字符串中传递密码的事实。例如:
(setq sql-connection-alist
'((my-db (sql-product 'postgres)
(sql-database "postgresql://user:pass@host/database"))))
然后禁用除数据库之外的所有postgres登录参数。
作为奖励,这里是我使用unix密码管理器pass
的配置,我推荐它:
(defun my-pass (key)
(string-trim-right
(shell-command-to-string (concat "pass " key))))
(setq sql-connection-alist
'((db (sql-product 'postgres)
(sql-database (concat "postgresql://user:"
(my-pass "db/user")
"@host/database")))))
否则,必须使用非交互式身份验证方法(例如.pgpass
文件)。
我最初(也是不正确的)建议是在M-xcustomize-option
RETsql-postgres-login-params
RET处启用"密码"选项。
sql-*-login-params
变量(以及相关的自定义窗口小部件)在所有数据库类型中通用;但并非所有这些选项都适用于所有数据库。
在适用的情况下,密码由Emacs读取,然后在命令行中使用。然而,psql
不允许将密码作为命令的一部分提供,因此Emacs在这里无法使用这种方法。这就是为什么postgres登录参数的密码选项被禁用的原因。
我发现在sql-connection-alist
中显式定义连接是最简单的。一旦定义了连接,就可以使用sql-connect
进行连接。可以使用向上/向下/上一个/下一个来选择特定的连接。在连接read-passwd
时,请通过读取密码来避免存储密码。
;; Remove all default login parameters
(setq sql-postgres-login-params nil)
;; define your connections
(setq sql-connection-alist
'((primary-db (sql-product 'postgres)
(sql-database (concat "postgresql://"
"username" ;; replace with your username
":" (read-passwd "Enter password: ")
"@host" ;; replace with your host
":port" ;; replace with your port
"/database" ;; replace with your database
)))
(secondary-db (sql-product 'postgres)
(sql-database (concat "postgresql://"
"username:"
(read-passwd "Enter password: ")
"@host"
":port"
"/database")))))
首先,清除sql-postgres-login-params
变量。创建默认值毫无意义,因为它们将在连接列表中定义。如果sql-postgres-login-params
不是nil,则连接时会提示您。这很烦人,并且违背了明确定义连接的目的。
第二,使用";连接URI";以定义连接。
这些有以下形式:
postgresql://[user[:password]@][netloc][:port][,...][/dbname][?param1=value1&...]
在上面的示例中,我们将为postgres
创建名为primary-db
和secondary-db
的连接。连接仅使用";数据库";参数数据库是一个连接URI,通过将字符串连接成适当的形式来创建。看看read-passwd
是如何阻止我们存储密码的?将每个参数替换为自己的参数。注意主机(@
)、端口(:
)和数据库(/
)的各种语法元素。如果您不想存储特定的参数,我想您可以像使用read-passwd
一样使用read-string
,但这基本上是在重新设计使用sql-postgres-login-params
的工具。
有关列表的详细信息,请参见C-h i d g (elisp) Association Lists
。
我通过创建一个.pgpass文件暂时解决了这个问题,我在该文件中存储了我的连接凭据。我对此感到不舒服,我想要一个需要在登录时输入密码的解决方案。
我也有这个问题。如果你去空缓冲区&点击回车键,你会得到密码提示吗?我有,当输入密码时,模式工作得很好。
适用于设置PGPASSWORD
环境变量,例如(setenv "PGPASSWORD" "whatever your password is")
可以对sql-comint-postgres
进行猴子补丁,以使用带有标准连接列表字段的PGPASSWORD
环境变量:
(defun sql-comint-postgres (product options &optional buf-name)
"Create comint buffer and connect to Postgres."
;; username and password are ignored. Mark Stosberg suggests to add
;; the database at the end. Jason Beegan suggests using --pset and
;; pager=off instead of \o|cat. The later was the solution by
;; Gregor Zych. Jason's suggestion is the default value for
;; sql-postgres-options.
(let ((params
(append
(if (not (= 0 sql-port))
(list "-p" (number-to-string sql-port)))
(if (not (string= "" sql-user))
(list "-U" sql-user))
(if (not (string= "" sql-server))
(list "-h" sql-server))
options
(if (not (string= "" sql-database))
(list sql-database))))
(process-environment
(nconc
(list (format "PGPASSWORD=%s" sql-password))
process-environment)))
(message (prin1-to-string process-environment))
(sql-comint product params buf-name)))