我正在研究的theapp/settings.py
django应用程序与SQLite运行良好,但我遇到了删除/更新大型记录集的性能问题,因此我正在转换到PostgreSQL数据库。
为此,我开始通过更新assets/migrations/
来配置PostgreSQL,从一个新的数据库开始并删除./manage.py makemigrations assets
./manage.py migrate --run-syncdb
./manage.py createsuperuser
目录。我正在跑步:
post_create
我在注册的Scan
信号中调用了一个函数。它在创建assets.models.Scan
对象时运行扫描。在课程@classmethod
def post_create(cls, sender, instance, created, *args, **kwargs):
if not created:
return
from celery.result import AsyncResult
# get the domains for the project, from scan
print("debug: task = tasks.populate_endpoints.delay({})".format(instance.pk))
task = tasks.populate_endpoints.delay(instance.pk)
中:
from celery import shared_task
....
import datetime
@shared_task
def populate_endpoints(scan_pk):
from .models import Scan, Project,
from anotherapp.plugins.sensual import subdomains
scan = Scan.objects.get(pk=scan_pk) #<<<<<<<< django no like
new_entries_count = 0
project = Project.objects.get(id=scan.project.id)
....
违规代码:
DoesNotExist
引发的异常debug: task = tasks.populate_endpoints.delay(2)
[2017-09-14 23:18:34,950: ERROR/ForkPoolWorker-8] Task assets.tasks.populate_endpoints[4555d329-2873-4184-be60-55e44c46a858] raised unexpected: DoesNotExist('Scan matching query does not exist.',)
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/celery/app/trace.py", line 374, in trace_task
R = retval = fun(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/celery/app/trace.py", line 629, in __protected_call__
return self.run(*args, **kwargs)
File "/usr/src/app/theapp/assets/tasks.py", line 12, in populate_endpoints
scan = Scan.objects.get(pk=scan_pk)
:
./manage.py shell
通过Scan
进行交互但表示存在pk == 2的>>> from assets.models import Scan
>>> Scan.objects.all()
<QuerySet [<Scan: ACME Web Test Scan>]>
>>> s = Scan.objects.all().first()
>>> s.pk
2
个对象:
post_create
我唯一的猜测是,在调用Scan
函数时,save()
对象仍然不存在于PostgreSQL数据库中,尽管已调用DoesNotExist
。
SQLite没有出现这个问题
另外,我还没有在stackoverflow上找到相关的相关问题,因为console.log('No');
global.LoginList.findOne({"role": "admin", username: req.body.username.toLowerCase()}, function (error, data) {
console.log('Yes');
});
异常看起来相当通用并且由很多东西引起。
对此的任何想法都将非常感激。
答案 0 :(得分:1)
这是由事务和隔离级别产生的well known problem - 有时在执行任务时没有提交事务,如果您的隔离级别是READ COMMITED,那么您确实无法读取此记录另一个过程。 Django 1.9 introduced the on_commit
hook作为解决方案。
注意:从技术上讲,此问题与Django related objects are missing from celery task (race condition?)重复,但接受的答案使用django-transaction-hooks
,此后该问题已合并到django中。