В настоящее время я анализирую файл дампа Википедии; Я извлекаю из него кучу данных с помощью Python и сохраняю их в базе данных PostgreSQL. Я всегда стараюсь ускорить процесс, потому что этот файл огромен (18 ГБ). Для взаимодействия с PostgreSQL я использую psycopg2, но этот модуль, похоже, имитирует многие другие подобные DBAPI.
В любом случае, у меня есть вопрос относительно cursor.executemany (команда, значения); мне кажется, что выполнение executemany один раз каждые 1000 значений или около того лучше, чем вызов cursor.execute (значение команды%) для каждого из этих 5 миллионов значений (пожалуйста, подтвердите или исправьте меня!).
Но, как видите, я использую команду ВСТАВИТЬ 1000 строк в таблицу, которая имеет УНИКАЛЬНОЕ ограничение целостности; это ограничение не проверяется заранее в python, так как это либо потребует от меня постоянно выбирать SELECT (это кажется контрпродуктивным), либо потребует от меня более 3 ГБ ОЗУ. Все это говорит о том, что я рассчитываю на то, что Postgres предупредит меня, когда мой скрипт попытается ВСТАВИТЬ уже существующую строку, перехватив psycopg2.DatabaseError.
Когда мой скрипт обнаруживает такую не УНИКАЛЬНУЮ ВСТАВКУ, он connection.rollback () (который составляет до 1000 строк каждый раз и как бы делает выполнение многих бесполезными), а затем ВСТАВЛЯЕТ все значения одно за другим.
Поскольку psycopg2 так плохо документирован (как и многие отличные модули ...), я не могу найти действенного и действенного обходного пути. Я уменьшил количество значений, ВСТАВЛЯЕМЫХ для каждого исполнителя, с 1000 до 100, чтобы снизить вероятность неуникального ВСТАВКИ для каждого выполнения, но я почти уверен, что это способ просто сказать psycopg2 игнорировать эти исключения или сообщить курсор для продолжения выполнения.
По сути, это похоже на проблему, решение которой настолько простое и популярное, что все, что я могу сделать, это попросить, чтобы узнать о ней.
Еще раз спасибо!
INSERT row ON CONFLICT DO NOTHING
. - person Justin Anderson   schedule 06.05.2016