Как использовать многопроцессорную обработку в Python с Django для создания тысяч экземпляров моделей из xml-файла?

У меня есть скрипт, который анализирует данные из файла xml в модели Django. Он работает нормально, но в последнее время мы сталкиваемся с файлами с десятками тысяч моделей для создания, что невероятно замедляет процесс (до 40 минут на загрузку одного файла размером 20MB).

Я хотел бы попытаться использовать multiprocessing для ускорения, насколько это возможно, но я новичок в этом пакете. Вот текущая установка:

  • create_profiles_from_xml: это функция, которая циклически просматривает данные, извлеченные из xml, вызываемого xml_members, выскакивая по одному элементу за раз (это должно быть так из-за связи, которая может быть создана со следующим элементом или нет).
  • create_profile: это просто функция, которая обрабатывает данные, чтобы они совпадали с полями модели, а затем вызывает метод .create(), поэтому я опустил подробности этой функции здесь.
def create_profiles_from_xml(xml_members, device):
    profiles = []

    while len(xml_members) > 0:
        parent_member = members.pop(0)
        profile = create_profile(parent_member, parent=None)
        if profile:
            profiles.append(profile)

    return profiles
  • А вот что я пытался сделать с мультипочесыванием
from multiprocessing import Pool

def create_profiles_from_xml(xml_members, device):
    profiles = []

    pool = Pool(processes=cpu_count())
    profiles = pool.imap_unordered(create_profile, xml_members)
                
    return profiles

И каждый раз, когда я пытаюсь запустить его, я получаю эту ошибку:

Traceback (most recent call last):
  File "/home/user/.virtualenvs/omnio/lib/python3.8/site-packages/django/db/backends/base/base.py", line 235, in _cursor
    return self._prepare_cursor(self.create_cursor(name))
  File "/home/user/.virtualenvs/omnio/lib/python3.8/site-packages/django/db/backends/postgresql/base.py", line 223, in create_cursor
    cursor = self.connection.cursor()
psycopg2.InterfaceError: connection already closed
The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/user/.virtualenvs/omnio/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/home/user/.virtualenvs/omnio/lib/python3.8/site-packages/axes/middleware.py", line 49, in __call__
    failures_since_start = AxesProxyHandler.get_failures(request, credentials)
  File "/home/user/.virtualenvs/omnio/lib/python3.8/site-packages/axes/handlers/proxy.py", line 94, in get_failures
    return cls.get_implementation().get_failures(request, credentials)
  File "/home/user/.virtualenvs/omnio/lib/python3.8/site-packages/axes/handlers/database.py", line 75, in get_failures
    attempt_count = max(
  File "/home/user/.virtualenvs/omnio/lib/python3.8/site-packages/axes/handlers/database.py", line 77, in <genexpr>
    attempts.aggregate(Sum("failures_since_start"))[
  File "/home/user/.virtualenvs/omnio/lib/python3.8/site-packages/django/db/models/query.py", line 379, in aggregate
    return query.get_aggregation(self.db, kwargs)
  File "/home/user/.virtualenvs/omnio/lib/python3.8/site-packages/django/db/models/sql/query.py", line 489, in get_aggregation
    result = compiler.execute_sql(SINGLE)
  File "/home/user/.virtualenvs/omnio/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1140, in execute_sql
    cursor = self.connection.cursor()
  File "/home/user/.virtualenvs/omnio/lib/python3.8/site-packages/django/db/backends/base/base.py", line 256, in cursor
    return self._cursor()
  File "/home/user/.virtualenvs/omnio/lib/python3.8/site-packages/django/db/backends/base/base.py", line 235, in _cursor
    return self._prepare_cursor(self.create_cursor(name))
  File "/home/user/.virtualenvs/omnio/lib/python3.8/site-packages/django/db/utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/user/.virtualenvs/omnio/lib/python3.8/site-packages/django/db/backends/base/base.py", line 235, in _cursor
    return self._prepare_cursor(self.create_cursor(name))
  File "/home/user/.virtualenvs/omnio/lib/python3.8/site-packages/django/db/backends/postgresql/base.py", line 223, in create_cursor
    cursor = self.connection.cursor()
django.db.utils.InterfaceError: connection already closed
Вернуться на верх