2017-09-14 73 views
0

assets django應用程序我正在與SQLite運行良好,但我面臨性能問題與刪除/更新大型記錄集,所以我正在過渡到一個PostgreSQL數據庫。django DoesNotExist匹配查詢不存在與Postgres只

爲此,我開始更新theapp/settings.py來配置PostgreSQL,從新的數據庫開始並刪除assets/migrations/目錄。我然後運行:

./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函數時,儘管調用了save(),但PostgreSQL數據庫中仍然不存在Scan對象。
SQLite不會出現這個問題。
此外,我還沒有找到相關的問題,因爲DoesNotExist異常看起來是相當通用的,並由許多事情造成的。 對此的任何想法將不勝感激。

+0

兩個pks是否具有相同的類型?您尚未提供型號規格。如果你沒有明確地聲明它,它應該是整數。但是不確定在從一個數據庫遷移到另一個數據庫時這是否會成爲問題。 – Risadinha

回答

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中。

+0

感謝Bruno,我成功地在第一個鏈接中調整了「TransactionAwareTask」類代碼片段。 – user1330734

相關問題