为了将类似文件的对象复制到 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代码。
关于如何实现此目标的任何建议?
我意识到标志-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
。在这一点上,我想知道是否有可能通过子流程调用实现我想要的目标。