Как правильно использовать мультипроцессинг и блоки транзакций в 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.')
Отказ от ответственности: я не эксперт в области многопроцессорной обработки, я только начал увлекаться ею, пытаясь ускорить наши скрипты.