piping postgres COPY in python with psycopg2

后端 未结 2 1202
不知归路
不知归路 2021-02-06 06:55

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



        
相关标签:
2条回答
  • 2021-02-06 07:11

    You could use a deque that you've subclassed to support reading and writing:

    from collections import deque
    from Exceptions import IndexError
    
    class DequeBuffer(deque):
        def write(self, data):
            self.append(data)
        def read(self):
            try:
                return self.popleft()
            except IndexError:
                return ''
    
    buf = DequeBuffer()
    

    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 the deque 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.

    0 讨论(0)
  • 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:

    #!/usr/bin/python
    import psycopg2
    import os
    import threading
    
    fromdb = psycopg2.connect("dbname=from_db")
    todb = psycopg2.connect("dbname=to_db")
    
    r_fd, w_fd = os.pipe()
    
    def copy_from():
        cur = todb.cursor()
        cur.copy_from(os.fdopen(r_fd), 'table')
        cur.close()
        todb.commit()
    
    to_thread = threading.Thread(target=copy_from)
    to_thread.start()
    
    cur = fromdb.cursor()
    write_f = os.fdopen(w_fd, 'w')
    cur.copy_to(write_f, 'table')
    write_f.close()   # or deadlock...
    
    to_thread.join()
    
    0 讨论(0)
提交回复
热议问题