Saltar al contenido

¿Acelerar la inserción masiva usando el ORM de Django?

Esta es la solución más completa que encomtrarás compartir, sin embargo mírala detenidamente y analiza si es compatible a tu trabajo.

Solución:

Django 1.4 proporciona una bulk_create() método en el objeto QuerySet, consulte:

  • https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.bulk_create
  • https://docs.djangoproject.com/en/dev/releases/1.4/
  • https://code.djangoproject.com/ticket/7596

Esto no es específico de Django ORM, pero recientemente tuve que insertar en masa >60 millones de filas de 8 columnas de datos de más de 2000 archivos en una base de datos sqlite3. Y aprendí que las siguientes tres cosas redujeron el tiempo de inserción de más de 48 horas a ~1 hora:

  1. aumente la configuración del tamaño de caché de su base de datos para usar más RAM (las predeterminadas siempre son muy pequeñas, usé 3 GB); en sqlite, esto lo hace PRAGMA cache_size = n_of_pages;

  2. haga un diario en la RAM en lugar del disco (esto causa un pequeño problema si el sistema falla, pero algo que considero insignificante dado que ya tiene los datos de origen en el disco); en sqlite esto lo hace PRAGMA journal_mode = MEMORY

  3. el último y quizás el más importante: no construya el índice mientras inserta. Esto también significa no declarar ÚNICO u otra restricción que pueda hacer que la base de datos cree un índice. Cree el índice solo después de que haya terminado de insertar.

Como alguien mencionó anteriormente, también debe usar cursor.executemany() (o simplemente el atajo conn.executemany()). Para usarlo, haz:

cursor.executemany('INSERT INTO mytable (field1, field2, field3) VALUES (?, ?, ?)', iterable_data)

Iterable_data podría ser una lista o algo similar, o incluso un lector de archivos abiertos.

Vaya a DB-API y use cursor.executemany(). Ver PEP 249 para más detalles.

Sección de Reseñas y Valoraciones

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *