通过单一连接进行交易阻止的Python Postgres查询

时间:2018-11-02 03:38:14

标签: python postgresql newline greenplum

目前,我有两个单独的语句传递给Postgres(Greenplum)。 1.截断一个表 2.使用\ copy

加载数据
myStr="export PGPASSWORD=" + dbPass + "; psql -h " + dbHost + " -p " + dbPort + " -d " + dbName + " -U " + dbUser + " -c " + "\"" + "truncate table " + dbTable + ";\""
print(myStr)
subprocess.call(myStr,shell=True)
myStr="export PGPASSWORD=" + dbPass + "; psql -h " + dbHost + " -p " + dbPort + " -d " + dbName + " -U " + dbUser + " -c " + "\"" + "\\" + "copy " + dbTable + " from " + "'" + csvfile + "' with " + copyOpts + ";" + "select count(*) from " + dbTable + ";\""
print(myStr)
subprocess.call(myStr,shell=True)

有时加载有错误,但是截断已经发生,所以我试图在一个连接中运行两个语句,这样就可以在数据加载失败时以这种方式放置一个事务块(BEGIN ... COMMIT;)。将回滚到截断发生之前。

我尝试了以下方法:

myStr="export PGPASSWORD=" + dbPass + "; psql -h " + dbHost + " -p " + dbPort + " -d " + dbName + " -U " + dbUser + " -c " + "\"" + "truncate table " + dbTable + ";" + " \\" + "copy " + dbTable + " from " + "'" + csvfile + "' with " + copyOpts + ";" + "select count(*) from " + dbTable + ";\""
print(myStr)

解析为以下命令:

export PGPASSWORD=abcde; 
psql -h abcde.testserver.corp 
-p 5432 -d namem -U username -c 
"truncate table schema.example; 
\copy schema.example from 
'/home/testing/schema/schema.example_export.csv' 
with header null as '' escape 'off' delimiter E',' ;
select count(*) from schema.example;"

但是我遇到了错误:

  

错误:“ \”或附近的语法错误

我认为这是由于\命令必须放在单独的行上。

有没有一种方法可以将命令分成几行,以便我可以在单个连接中执行所有命令?

1 个答案:

答案 0 :(得分:0)

问题是,如果使用-c选项,则不能将反斜杠命令与其他命令分开。您可以使用STDIN通过psql发送命令到echo

export PGPASSWORD=abcde;
echo "truncate table schema.example; 
\copy schema.example from '/home/testing/schema/schema.example_export.csv' with header null as '' escape 'off' delimiter E',' ;
select count(*) from schema.example;" | psql -h abcde.testserver.corp -p 5432 -d namem -U username

有点笨拙。最好使用subprocess.Popen

theCommand = """truncate table schema.example; 
\copy schema.example from 
'/home/testing/schema/schema.example_export.csv' 
with header null as '' escape 'off' delimiter E',' ;
select count(*) from schema.example;"""
theProcess = subprocess.Popen("psql -h abcde.testserver.corp -p 5432 -d namem -U username", 
    stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
theOutput, theErrors = theProcess.communicate(input = theCommand)

但是最好的方法应该是避免使用shell命令并使用诸如PyGreSQL之类的数据库适配器。