psycopg2 COPY使用cursor.copy_from()冻结大输入

时间:2010-08-16 09:15:35

标签: python postgresql large-data-volumes psycopg2

使用psycopg2 cursor对象考虑Python中的以下代码(为清楚起见,更改或省略了一些列名称):

filename='data.csv'
file_columns=('id', 'node_id', 'segment_id', 'elevated', 
              'approximation', 'the_geom', 'azimuth')
self._cur.copy_from(file=open(filename),
                    table=self.new_table_name, columns=file_columns)
  • 数据库位于快速LAN上的远程计算机上。
  • 使用bash中的\COPY工作速度非常快,即使对于大型(~1,000,000行)文件也是如此。

此代码对5,000行非常快,但当data.csv超过10,000行时,程序会完全冻结。

任何想法\解决方案?

亚当

2 个答案:

答案 0 :(得分:5)

这只是一种解决方法,但您可以将内容传递给psql。有时当我懒得忘掉psycopg2时,我会使用这个食谱

import subprocess
def psql_copy_from(filename, tablename, columns = None):
    """Warning, this does not properly quote things"""
    coltxt = ' (%s)' % ', '.join(columns) if columns else ''
    with open(filename) as f:
        subprocess.check_call([
            'psql',
            '-c', 'COPY %s%s FROM STDIN' % (tablename, coltxt),
            '--set=ON_ERROR_STOP=true', # to be safe
            # add your connection args here
        ], stdin=f)

就你的锁定而言,你使用的是多线程还是其他类似的东西?

你的postgres是否记录了诸如关闭连接或死锁之类的内容?锁定后你能看到磁盘活动吗?

答案 1 :(得分:1)

这是内存限制,使“copy_from”崩溃为open(filename)一次性返回所有文件。这是psycopg2的问题,而不是Postgresql问题,所以迈克的解决方案是最好的。

如果您想在常规提交中使用“copy_from”并同时管理重复键,则有一个解决方案: https://stackoverflow.com/a/11059350/1431079