如何从python调用和管道传递多个postgres命令

时间:2019-06-18 12:04:02

标签: python-3.x postgresql command-line pipe

为了将类似文件的对象复制 postgres 数据库,我采取以下步骤:

~$ sudo psql -U postgres
password for root: 
password for user postgres:
postgres=# \c migration v0
You are now connected to database "migration_v0" as user "postgres".
migration_v0=# cat file.csv | \copy table1 from stdin csv

我想采取完全相同的步骤,但是要从 Python 内部进行,并希望传递StringIO缓冲区而不是文字文件。我的第一次尝试包括以下步骤:

# test.py

fmt = r"copy table1 FROM stdin csv"
sql = fmt.format(string_io)
psql = ['psql', '-U', 'postgres', '-c', sql]
output = subprocess.check_output(psql)
print(output)

该命令已执行(弹出提示以键入用户 postgres 的密码),但出现以下错误:

  

错误:关系“ table1”不存在

发生这种情况是因为我当前正在尝试在默认数据库\copy而非postgres上执行migration_v0。因此,我想将两个命令都包含在子流程调用中(\c migration_v0\copy ...),但我不知道该怎么做,因为postgres的标志-c只需要一个命令。

我查找了一种解决方法,并遇到了以下命令行示例:

\c migration_v0 \\ \copy ... | psql -U postgres

,但是我不知道如何将其移植到python代码。

关于如何实现此目标的任何建议?

编辑1

我意识到标志-d也可以切换数据库,所以现在我不需要运行多个命令。我的代码现在看起来像这样:

p = subprocess.Popen([
                         'psql', '-U', 'postgres', 
                         '-d', 'migration_v0', 
                         '-c', '\copy table1 FROM stdin csv'], 
                      shell=False, 
                      stdin=string_io)

但出现以下错误:

  

io.UnsupportedOperation:文件编号

显然,StringIO没有实现fileno。在这一点上,我想知道是否有可能通过子流程调用实现我想要的目标。

0 个答案:

没有答案