psycopg2 COPY с использованием cursor.copy_from () зависает с большими входами

Рассмотрим следующий код на 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 строк, программа полностью зависает.

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

Адам


person Adam Matan    schedule 16.08.2010    source источник


Ответы (2)


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

person mikelikespie    schedule 18.08.2010
comment
+1 Спасибо, это решение, которое я использовал, с немного другим синтаксисом. Признаков тупиковых ситуаций не вижу, дисковая активность в норме (это довольно загруженный сервер). - person Adam Matan; 18.08.2010

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

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

person Le Droid    schedule 15.06.2012