【问题标题】:Apps aren't loaded yet exception occurs when using multi-processing in Django在 Django 中使用多处理时发生应用程序尚未加载的异常
【发布时间】:2017-10-24 10:23:14
【问题描述】:

我正在做一个 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中,但这会导致错误。

我的问题是

  • 为什么导入转换模型会导致Apps are not loaded yet错误,我google了很多文章但实际上并没有解决我的问题。
  • 我可以看到生成的每个 Process SpawnPoolWorker-x 并尝试再次启动 django 服务器(为什么?),每个工作人员都会在相同的错误处停止。

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

【问题讨论】:

  • 不要这样做。使用 Celery 之类的东西来运行离线作业。
  • 请问如果使用多处理会有什么问题?我在 django 中尝试了一些简单的数学计算,它可以工作,但是当我尝试调用另一个模块时,它会失败并停止并出现此错误。
  • 我知道这对于 Web 应用程序(同步执行)来说是不寻常的,但假设我只想在本地机器(127.0.0.1)上安装应用程序,而不是作为 Web 服务器托管。有没有办法通过多处理来加速计算任务?

标签: django multiprocessing


【解决方案1】:

对于将来可能会偶然发现此问题的其他人:

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

绕过它:

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

【讨论】:

  • 默认取决于操作系统。根据文档,只有在 MacOS 上,默认值更改为 3.8,并且 fork 在那里被认为是不安全的。 “在 macOS 上,spawn start 方法现在是默认设置。fork start 方法应该被认为是不安全的,因为它可能导致子进程崩溃。请参阅 bpo-33725。”
  • 我在这里缺少什么?我正在查看的文档说默认启动方法是在 Windows 和 Mac OS 上生成的:docs.python.org/3.8/library/multiprocessing.html
  • 我猜有两件事。 1.有3个主要操作系统。所以评论“默认进程启动方法是'spawn'。”仅适用于 3 个中的 2 个。 2. Windows 上的默认设置是 ALWAYS spawn。所以声明“这是 Python 3.8 的一个变化,默认进程启动方法从 'fork' 更改为 'spawn'”仅适用于 3 个操作系统中的 1 个。
【解决方案2】:

这个帖子可以解决问题。

Django upgrading to 1.9 error “AppRegistryNotReady: Apps aren't loaded yet.”

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

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

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

【讨论】:

    猜你喜欢
    • 2016-08-22
    • 1970-01-01
    • 2019-05-10
    • 2017-08-21
    • 1970-01-01
    • 1970-01-01
    • 2014-12-15
    • 2018-11-29
    • 1970-01-01
    相关资源
    最近更新 更多