将用户名和密码插入数据库时​​出错

时间:2014-09-25 20:06:47

标签: bash postgresql shell

我正在尝试在psql中插入以下数据,它显示我奇怪的错误。

      -bash-4.1$ psql -t -d mydb -c 'insert into ftp_mgr (id, info) values("192.168.1.12",       '{"username": "Administrator", "password": "abc456$", "serverAddr":"192.168.1.12"}');'

      psql: warning: extra command-line argument "password:" ignored
      psql: warning: extra command-line argument "abc456$," ignored
      psql: warning: extra command-line argument "serverAddr:192.168.1.12});" ignored
      psql: FATAL:  role "Administrator," does not exist

1 个答案:

答案 0 :(得分:0)

这与PostgreSQL无关。这是一个引用shell的问题。

无法在bash中嵌套单引号。所以这个:

'insert into ftp_mgr (id, info) values("192.168.1.12",       '{"username": "Administrator", "password": "abc456$", "serverAddr":"192.168.1.12"}');'

读起来:

'insert ...'{

并且{不是引用字符串的一部分。所以shell试图将{"username": "Administrator", "password": "abc456$", "serverAddr":"192.168.1.12"}解释为shell命令。


这里最简单的方法是使用引用的here-document来避免需要处理'字面引用混合shell的引用:

psql -t -d mydb <<'__END__'
insert into ftp_mgr (id, info) values
("192.168.1.12", '{"username": "Administrator", "password": "abc456$", "serverAddr":"192.168.1.12"}');
__END__

here-document标记周围的引号是 important 。如果你把它们排除在外,那么bash仍会在here-document文本中查找并替换$variable字符串等。这可能非常方便,但在这种情况下,它显然不是你想要的。


如果您必须使用-c,则可以选择以下几种方法:

使用shell的字符串连接。无论何时需要单引号,都要结束当前单引号字符串,写入"'",然后打开一个新的单引号字符串。所以你要写:

'insert ... values(..., '"'"'{"....

难以阅读,不是吗?第一个'结束单引号shell字符串。然后"'"是单引号,由双引号引用,由shell消耗。然后,下一个'开始一个新的单引号字符串。

阅读起来太可怕了,而且写得不太好:

'insert ... values(..., '\''{"....

所以个人而言,当我在参数字符串中需要单引号时,我要么双引号整个字符串和反斜杠转义shell元字符:

  "insert into ftp_mgr (id, info) values(\"192.168.1.12\", '{\"username\": \"Administrator\", \"password\": \"abc456\$\", \"serverAddr\":\"192.168.1.12\"}');"

......或者在可能的情况下,我使用引用文件来解决整个可怕的混乱。


我的首选是避免使用shell来处理这类事情并使用简单的Python脚本。

import psycopg2
conn = psycopg2.connect('dbname=postgres')
curs = conn.cursor()
curs.execute(r'insert into ftp_mgr (id, info) values(%s, %s);', (
     r'192.168.1.12',
     r'{"username": "Administrator", "password": "abc456$", "serverAddr":"192.168.1.12"}'
   ))

Python对原始字符串(r''),三引号字符串(""")等的支持使得这类事情变得更加容易。