【发布时间】:2020-04-15 09:23:55
【问题描述】:
我可以通过什么方式从 Python 脚本执行 psql 命令?我的代码从 PostgreSQL 数据库插入和更新数据(使用 psycopg2 和游标方法)。当我执行像
这样的查询时,它工作正常cursor.execute("UPDATE Segment set idcurve = %s where id = %s ", (id_curve, id_segment,))
但是在 psql 的情况下,当我将命令传递给 cursor.execute (see edits to similar question) 时,我得到了 SyntaxError: syntax error at or near "\"。
此外,该命令在 console.sql DataGRIP 中失败(无论如何它都会对所有行执行......)
这个命令是否只能在 shell 中工作(我必须使用 os.system)吗?因为cursor 无法解释?
编辑 尝试使用子进程:
import subprocess
sql = """SELECT uuid IS NULL AS is_uuid FROM dpoint WHERE uuid = '5547f4b7-00b3-4aac-8ceb-c9ca163a0214';
\gset
\if :is_uuid
INSERT INTO DPoint (uuid) VALUES ('5547f4b7-00b3-4aac-8ceb-c9ca163a0214');
WITH ins1 AS (INSERT INTO Point (latitude, longitude, srid)
VALUES (64.44, 28.77, 4326) RETURNING id AS id_point)
INSERT INTO SPoint (idPoint, uuiddpt) VALUES ((SELECT id_point FROM ins1), '5547f4b7-00b3-4aac-8ceb-c9ca163a0214');
\endif
"""
subprocess.check_call(['psql -h localhost -d dbase -U myuser -W --command={}'.format(sql)], env={'PGPASSWORD': 'mypass'})
抛出OSError: [Errno 36] File name too long
EDIT2
subprocess.check_call(['psql', '-q', '-U', 'myuser', '-h', 'localhost', '-c', '{}'.format(sql), 'dbase'], env={'PGPASSWORD': 'mypass'})
当我拆分查询尝试执行的所有参数时 -> 它以syntax error at or near "\" 失败。 -E(正如 Lu M 建议的那样)没有帮助。它适用于我将查询保存到 .sql 文件但我想以交互方式执行它的情况。
EDIT3
根据章节--command=command 中的psql tutorial,有两个选项可用于混合SQL 和psql 元命令。以什么方式可以将其包装在子流程中? 我都尝试了,但出现了不需要的额外反斜杠,并且它不被识别为一个命令:
subprocess.check_call(['psql', '-q', '-U', 'myuser', '-h', 'localhost',
'-c', '{}'.format(sql),
'-c', '{}'.format('\gset'),
'-c', '{}'.format('\if :is_uuid '),
'-c', '{}'.format(sql2),
'-c', '{}'.format('\endif'), 'dbase'],
env={'PGPASSWORD': 'mypass'})
unrecognized value ":is_uuid" for "\if expression": Boolean expected 失败
【问题讨论】:
-
以
` are, as you already guessed,psql`命令开头的命令,不是由DBMS本身解释,而是由psql程序解释。 -
@stickybit 这个答案stackoverflow.com/a/19930714/8129993 仍然有效并且是最新的吗?
-
好吧,你为什么不试试看它是否适合你?
-
我正在尝试,但没有成功(请参阅我的问题的编辑)
-
理论上你可以重写它以使用常规 sql,但我不确定它应该做什么。第一个查询要么不返回任何内容,要么返回 false。
标签: python sql postgresql subprocess psql