应用程序尚未加载,在 Django 中使用多处理时出现异常

问题描述 投票:0回答:3

我正在做一个Django项目,并尝试提高后端的计算速度。

该任务类似于受 CPU 限制的转换过程

这是我的环境

  • Python 3.6.1
  • Django 1.10
  • PostgreSQL 9.6

当我尝试通过 python 多处理库并行计算 API 时,我遇到了以下错误。

  File "D:\\project\apps\converter\models\convert_manager.py", line 1, in <module>
    from apps.conversion.models import Conversion
  File "D:\\project\apps\conversion\models.py", line 5, in <module>
    class Conversion(models.Model):
  File "C:\\virtenv\lib\site-packages\django\db\models\base.py", line 105, in __new__
    app_config = apps.get_containing_app_config(module)
  File "C:\\virtenv\ib\site-packages\django\apps\registry.py", line 237, in get_containing_app_config
    self.check_apps_ready()
  File "C:\\lib\site-packages\django\apps\registry.py", line 124, in check_apps_ready
    raise AppRegistryNotReady("Apps aren't loaded yet.")

貌似各个流程导入转换模型 转换模型就像

from django.db import models


    Conversion(model.Model):

       conversion_name = models.CharField(max_length=63)
       conversion_user = models.CharField(max_length=31)
       conversion_description = models.TextField(blank=True)
       ...

下面是我想要并行的示例函数,每次迭代都是独立的,但会访问数据或将数据插入到 SQL 中。

Class ConversionJob():
     ...

    def run(self, p_list):
        list_merge_result = []
        for p in p_list:
            list_result = self.Couputing_api(p)
            list_merge_result.extend(list_result)

我正在尝试做的是

from multiprocessing import Pool


 Class ConversionJob():
         ...
        def run(self, p_list):
            list_merge_result = []

            p = Pool(process=4)
            list_result = p.map(self.couputing_api, p_list)
            list_merge_result.extend(list_result)

在computing_api()中,它会尝试在调用此api之前获取当前已完成的转换信息并保存到SQL中,但这导致了错误。

我的问题是

  • 为什么导入Conversion模型会导致Apps isn't returned的错误,我google了很多文章但没有真正解决我的问题。
  • 我可以看到生成的每个进程 SpawnPoolWorker-x 并尝试再次启动 django 服务器(为什么?),每个工作线程都会因相同的错误而停止。

  • 计算API会尝试访问sql,我还没想好如何处理这个工作。 (在每个进程中共享数据库连接或创建新连接)

django multiprocessing
3个回答
24
投票

对于将来可能会偶然发现这一点的其他人:

如果您在运行 Python 3.8 并尝试使用多处理包时遇到此问题,很可能是因为子处理是“生成”而不是“分叉”。这是 Mac OS 上 Python 3.8 的一项更改,其中默认进程启动方法从“fork”更改为“spawn”。 这是 Django 的已知问题

绕过它:

import multiprocessing as mp
mp.set_start_method('fork')

7
投票

这篇文章可以解决这个问题。

Django 升级到 1.9 错误“AppRegistryNotReady:应用程序尚未加载。”

我以前就找到过这个答案,但当时并没有真正解决我的问题。

经过我反复测试,我必须在导入另一个模型之前添加这些代码, 否则,子进程将启动失败并给出错误。

import django
django.setup()
from another.app import models

0
投票

如果您使用 set_start_method('fork') ,则很可能已经设置了 start 方法,并且它将引发“RuntimeError:上下文已被设置”。在这种情况下,您可以将“force”参数设置为 True https://docs.python.org/3/library/multiprocessing.html#multiprocessing.set_start_method

multiprocessing.set_start_method('fork', force=True)

或者您可以使用自定义上下文而不是默认上下文创建池:

ctx = multiprocessing.get_context("fork")
with ctx.Pool() as pool:
    ...
© www.soinside.com 2019 - 2024. All rights reserved.