psycopg2 COPY с помощью cursor.copy_from () зависает с большими входами - PullRequest
0 голосов
/ 16 августа 2010

Рассмотрим следующий код в Python, использующий объект psycopg2 cursor (некоторые имена столбцов были изменены или опущены для ясности):

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)
  • База данных расположена на удаленном компьютере в быстрой локальной сети.
  • Использование \COPY от bash работает очень быстро, даже для больших (~ 1 000 000 строк) файлов.

Этот код является сверхбыстрым для 5000 строк, но когда data.csv выходит за пределы 10 000 строк, программа полностью зависает.

Есть мысли \ решения?

Адам

Ответы [ 2 ]

5 голосов
/ 18 августа 2010

Это просто обходной путь, но вы можете просто передать что-то в 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 голос
/ 16 июня 2012

Это ограничение памяти, которое приводит к сбою «copy_from», поскольку open (имя файла) возвращает весь файл за один снимок.Это проблема psycopg2, а не Postgresql, поэтому решение Майка является лучшим.

Существует решение, если вы хотите использовать «copy_from» с регулярными коммитами и одновременно управлять дублирующимися ключами: https://stackoverflow.com/a/11059350/1431079

...