Пакетная вставка psycopg2 с неверными данными - PullRequest
0 голосов
/ 09 апреля 2020

Я строю сценарий ETL, используя Python и psycopg2. Исходная и целевая базы данных postgres. Он работает нормально, но немного медленно.

Структура моей программы такая:

import psycopg2

# create the database connections, see https://www.psycopg.org/docs/cursor.html#cursor
source_cursor = source_database_connection.conn.cursor()
destination_cursor = destination.conn.cursor()

insert_query = "INSERT INTO mytable (col1, ..., coln) VALUES (%s, ..., %s)  ON CONFLICT (key) DO UPDATE SET col1 = value1, ... ;"

for row in source_cursor:
    # data is a list with varying data types
    # mock example: data = [10, 'foo', 'bar', 123]
    # 123 might be a foreign key in mytable2
    data = some_business_logic(row)
    try:
        destination_cursor.execute(insert_query, data)
    except:
        # skip this row, log the error

Моя исходная таблица содержит около 10 миллионов записей, так что это занимает некоторое время. Чтобы ускорить процесс, я бы хотел использовать пакетную INSERT. psycopg2 предоставляет несколько вариантов для этого, а именно execute_batch() и execute_values() ( ссылка на документацию ). L oop будет выглядеть примерно так:

data = []
for row in source_cursor:
    # create a list of tuples with data, 
    # mock example: data =  [(10, 'foo', 'bar', '123'), (11, 'foo2', 'bar2', '124'), ...]
    data += [tuple(some_business_logic(row))]
    if num_row %10000 == 0: # or whatever batch size we want
        try:
            destination_cursor.execute_values(insert_query, data)
            data = []
        except:
            # skip all rows, log the error

Это более или менее работает, но у меня слишком много ошибок в моих данных, чтобы выбросить весь пакет, когда есть плохая строка. Я мог бы перебрать все строки в data -вводах в except -блоке, но это выглядит довольно плохо с точки зрения производительности (в худшем случае я выполняю каждый запрос дважды).

Is Есть ли способ ускорить INSERT ... операторов при изящной обработке ошибок в то же время?

Спасибо!

...