我正在尝试在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
答案 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''
),三引号字符串("""
)等的支持使得这类事情变得更加容易。