Actualmente estoy analizando un archivo de volcado de wikipedia; Estoy extrayendo un montón de datos de él usando Python y persistiéndolo en un DB de PostgreSQL. Siempre trato de hacer que las cosas vayan más rápido porque este archivo es enorme (18GB). Para poder interactuar con PostgreSQL, estoy usando psycopg2, pero este módulo parece imitar a muchos otros DBAPI.Interfaz psycopg2 de Python-PostgreSQL -> executemany
De todos modos, tengo una pregunta sobre cursor.executemany (comando, valores); me parece como ejecutar un executemany una vez cada 1000 valores más o menos es mejor que llamar a cursor.execute (comando% value) para cada uno de estos 5 millones de valores (¡por favor, confírmame o corrígeme!).
Pero, verá, estoy usando una ejecución para INSERTAR 1000 filas en una tabla que tiene una restricción de integridad ÚNICA; esta restricción no se verifica en python de antemano, ya que esto requeriría SELECCIONARme todo el tiempo (esto parece contraproducente) o requerir que obtuviera más de 3 GB de RAM. Todo esto para decir que cuento con Postgres para advertirme cuando mi script intentó INSERTAR una fila ya existente mediante la captura de psycopg2.DatabaseError.
Cuando mi script detecta un INSERT no ÚNICO, connection.rollback() (que crea ups en 1000 filas cada vez, y hace que la ejecución many inútil) y luego INSERT todos los valores uno por uno.
Dado que psycopg2 está tan poco documentado (como lo son tantos módulos excelentes ...), no puedo encontrar una solución eficiente y efectiva. He reducido el número de valores INSERTed por execute many de 1000 a 100 para reducir la probabilidad de un INSERT no ÚNICO por ejecución, pero estoy bastante seguro de que es una forma de decirle a psycopg2 que ignore estas excepciones o que diga al cursor para continuar la ejecución many.
Básicamente, este parece ser el tipo de problema que tiene una solución tan fácil y popular, que todo lo que puedo hacer es preguntar para aprender sobre él.
¡Gracias nuevamente!
No estoy seguro, pero creo que executemany simplemente itera sobre su lista de diccionarios (filas) y llama a "insertar" en cada uno. Por lo tanto, no importa si se ejecuta ejecutar en un bucle o ejecutar executemany. Solo que el "commit" no se debe invocar en bucle, sino una vez cada 100 o 1000, según corresponda. –
así es como: outerloop-> obtiene 1000 filas siguientes de la lista -> da al bucle interno -> ejecuta para cada-> bucle interno sale -> confirmar -> bucle externo continúa hasta que duren los datos. Puedes probarlo en un conjunto de datos de 100,000 contra el ejecutable y comprobar si hace una diferencia. –
JV, ¿entonces estás diciendo que una ejecución todavía IPC se comunica con postgeSQL para cada INSERT? Es la sobrecarga inherente al IPC que espero eliminar al utilizar executemany; si no elimina esto, no tengo suficiente razón para usarlo. ¡Gracias, pero aún necesito más convicción! -Nick –