Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在多处理过程中,如何在异常后重置Django事务?_Python_Django_Python Multiprocessing - Fatal编程技术网

Python 在多处理过程中,如何在异常后重置Django事务?

Python 在多处理过程中,如何在异常后重置Django事务?,python,django,python-multiprocessing,Python,Django,Python Multiprocessing,发生数据库异常(例如IntegrityError)后,如何重置Django事务,以便继续写入数据库 我有几个工人在自己的流程中运行,所有这些流程都是通过joblib包启动的,该流程数据库记录。他们都通过Django的ORM将进度写入数据库 一般来说,它们工作正常,但偶尔,如果遇到错误,例如试图用违反唯一约束的列写入记录,则会抛出IntegrityError 我有错误处理逻辑来捕获这些,记录错误,并允许它跳到下一个要处理的文件。但是,我发现一旦遇到其中一个错误,就会有效地阻止该工作者进一步访问数据

发生数据库异常(例如IntegrityError)后,如何重置Django事务,以便继续写入数据库

我有几个工人在自己的流程中运行,所有这些流程都是通过
joblib
包启动的,该流程数据库记录。他们都通过Django的ORM将进度写入数据库

一般来说,它们工作正常,但偶尔,如果遇到错误,例如试图用违反唯一约束的列写入记录,则会抛出IntegrityError

我有错误处理逻辑来捕获这些,记录错误,并允许它跳到下一个要处理的文件。但是,我发现一旦遇到其中一个错误,就会有效地阻止该工作者进一步访问数据库,因为所有进一步的写入尝试都会返回臭名昭著的错误:

django.db.transaction.TransactionManagementError: An error occurred in the current transaction. You can't execute queries until the end of the 'atomic' block.
奇怪的是,我没有直接使用
atomic()
,所以我假设这是Django在某处隐式运行的。我如何解决这个问题

我知道避免此错误的通常方法是显式地将写操作包装在
原子
中。所以我尝试了这个方法,但是,这只会导致大量死锁错误,因为使用
atomic
around table编写由多个工作进程运行的代码意味着它们都是相互踩在一起的。即使我实现了错误处理代码以在死锁发生时重新运行写操作,我发现这实际上禁用了我的多处理功能。我没有让N个工作进程并行快速运行,而是让N个工作进程串行缓慢运行,因为它们都在等待彼此写入同一个表,即使99.99%的时间它们没有写入冲突行或违反任何约束

如何防止Django将所有内容包装在原子()中,以便通过
事务。回滚()
手动重置事务

我用如下脚本启动我的工人:

#!/usr/bin/env python
import django
from django.db import connection
django.setup() # Fixes joblib error "A task has failed to un-serialize"

from joblib import Parallel, delayed
from tqdm import tqdm

from myapp.models import Record

def do_work(record_id):
    record = Record.objects.get(id=record_id)
     ...do stuff and then write to Record...

records = Record.objects.filter(pending=True)
parallel_tasks = [delayed(do_work)(record.id) for record in records]
connection.close()
list(Parallel(n_jobs=cpu_count())(tqdm(parallel_tasks)))