Как правильно использовать мультипроцессинг и блоки транзакций в Django?

Как я могу использовать мультипроцессинг в Python/Django в командах управления или представлениях с блоками транзакций. Я хочу, чтобы, например, в представлении создавалось много данных, но если возникнет какое-либо исключение, я хотел бы откатить транзакцию и ничего не создавать. С другой стороны, иногда мы создаем команды управления, например, скрипты для запуска в миграциях для исправления данных, и мы также хотели бы использовать многопроцессорную обработку для ускорения, но с возможностью сделать dry-run скрипта, чтобы транзакция была откачена.

Я не могу использовать bulk_create в этих ситуациях, потому что модели, которые меня интересуют для изменения/создания, являются наследуемыми моделями, а bulk create не применяется к моделям такого типа.

Обернув транзакциями либо handle(), some_func, либо with Pool... блок, я получаю ошибку:

django.db.utils.InterfaceError: connection already closed
from multiprocessing import cpu_count, Pool

def worker_init():
    connection.close()

class Command(BaseCommand):
    # arguments here...
    
    def handle(self, *args, **options):
        self.commit = options['commit']

        try:
            # Wrapping the core of the script in a transaction block does not work
            # with transaction.atomic:
            items = [...]
            results = []
            with Pool(processes=cpu_count(), initializer=worker_init) as pool:
                for result in pool.imap_unordered(some_func, items):
                    results.extend(result)
            if not self.commit:
                raise Exception()

        except Exception:
            self.stdout.write(
                'DRY RUN: Command ran successfully but no changes were committed to the database.')

Отказ от ответственности: я не эксперт в области многопроцессорной обработки, я только начал увлекаться ею, пытаясь ускорить наши скрипты.

Вернуться на верх