使用 psycopg2 在 python 中管道 postgres COPY
我正在编写一个脚本,使用 psycopg2 在同一网络上的两台机器之间复制一些数据。我正在替换一些旧的、丑陋的 bash 来进行复制,
psql -c -h remote.host "COPY table TO STDOUT" | psql -c "COPY table FROM STDIN"
这似乎是最简单的 最有效的 复制方法。使用 stringIO 或临时文件在 python 中复制很容易,如下所示:
buf = StringIO()
from_curs = from_conn.cursor()
to_curs = to_conn.cursor()
from_curs.copy_expert("COPY table TO STDOUT", buf)
buf.seek(0, os.SEEK_SET)
to_curs.copy_expert("COPY table FROM STDIN", buf)
...但这涉及将所有数据保存到磁盘/内存中。
有没有人想出一种方法来在这样的副本中模仿 Unix 管道的行为?我似乎找不到不涉及 POpen 的 unix-pipe 对象 - 毕竟,也许最好的解决方案就是只使用 POpen 和子进程。
I'm writing a script to do a copy of some data between two machines on the same network using psycopg2. I'm replacing some old, ugly bash that does the copy with
psql -c -h remote.host "COPY table TO STDOUT" | psql -c "COPY table FROM STDIN"
This seems like both the simplest and most efficient way to do the copy. It's easy to replicate in python with a stringIO or a temp-file, like so:
buf = StringIO()
from_curs = from_conn.cursor()
to_curs = to_conn.cursor()
from_curs.copy_expert("COPY table TO STDOUT", buf)
buf.seek(0, os.SEEK_SET)
to_curs.copy_expert("COPY table FROM STDIN", buf)
...but that involves saving all the data to disk/in memory.
Has anyone figured out a way to mimic the behavior of a Unix pipe in a copy like this? I can't seem to find a unix-pipe object that doesn't involve POpen - Maybe the best solution is to just use POpen and subprocess, after all.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您必须将其中一个调用放在一个单独的线程中。我刚刚意识到你可以使用 os.pipe() ,这使得其余的非常简单:
You will have to put one of your calls in a separate thread. I just realized you can use os.pipe(), which makes the rest quite straightforward:
您可以使用已子类化的双端队列来支持读取和写入:
如果读取器比写入器快得多,并且表很大,则双端队列仍然会变大,但它会比存储整个东西要小。
另外,我不确定当
deque
为空时return ''
是否安全,而不是重试直到它不为空,但我猜是这样。让我知道它是否有效。当您确定复制完成时,请记住
del buf
,特别是如果脚本此时不只是退出的话。You could use a deque that you've subclassed to support reading and writing:
If the reader is much faster than the writer, and the table is large, the
deque
will still get big, but it will be smaller than storing the whole thing.Also, I don't know for sure
return ''
when thedeque
is empty is safe, rather than retrying until it's not empty, but I'd guess it is. Let me know if it works.Remember to
del buf
when you're sure the copy is done, especially if the script isn't just exiting at that point.