簡體   English   中英

Django Model 異步中的屬性 Function 從同步視圖中調用

[英]Django Model Property in Async Function Called from Sync View

我需要轉換我的一些 Django 視圖以使用查詢數據源的異步函數。 我遇到了很大的性能問題,因為這些查詢是逐個執行的。 然而,這項任務比預期的要困難得多。

我在下面指出了問題的開始。 我也遇到了其他問題,但是,到目前為止,這是我不知道該怎么做的問題。 我收到以下代碼中指示的以下錯誤:

django.core.exceptions.SynchronousOnlyOperation:您不能從異步上下文中調用它 - 使用線程或 sync_to_async

model2 是指向另一個 Model 的 ForeignKey 屬性。

在 sync_to_async() 中包裝 model1.model2 不起作用。

知道如何進行這項工作嗎?

async def queryFunctionAsync(param1, param2, loop):
   model1 = await sync_to_async(Model1.objects.get)(pk=param1)
   model2 = model1.model2 # This is where the error is generated

def exampleView(request):
   loop = asyncio.new_event_loop()
   asyncio.set_event_loop(loop)
   data = async_to_sync(queryFunctionAsync)(param1, param2, loop)
   loop.close()

假設您有某種 Django 視圖,並且當您向view發出請求時,您希望 function 在后台運行以提高view的響應時間。 如果您必須將它們轉換為同步以使它們與您的視圖兼容或在任何地方插入await ,那么使用異步函數沒有多大意義。

如果是我,我會推薦使用像celery這樣的事件流框架,這將允許您在后台運行任務並從您的 django 視圖大規模卸載處理。 例如,django 視圖允許用戶將消息發布到論壇,您可能會在消息發送后進行一些自然語言處理。 您可以將處理卸載到@shared_task中的@shared_task ,而不是阻止您的 django 視圖線程,這將改善 UX。

celery 池中的工作人員將從隊列中提取任務並在后台執行處理。 后台處理完成后,您可以使用django-channels websockets來提醒用戶任務完成以及需要呈現給客戶端的任何結果。 Celery還允許您使用稱為chord callback的概念將多個任務鏈接在一起並等待結果返回。

隨着您的查詢花費更長的時間並且數據集的大小增加,您還可以利用平面文件數據庫服務(例如elasticsearchmongodb來提高更高級的大規模嵌套查詢的性能。

這對我有用:

model2 = await sync_to_async(lambda: model1.model2)()

之后 model1 還包含參考。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM