【问题标题】:Where to up django app startup code that must interact with the database?必须与数据库交互的 django 应用程序启动代码在哪里?
【发布时间】:2020-01-12 09:10:37
【问题描述】:

我有一些 django 代码需要在我的应用程序加载到开发服务器或作为 wsgi 工作者时运行一次。这段代码也需要写入数据库。在我的特殊情况下,我不需要为许多管理命令(如 collectstatic 或 createsuperuser 等)运行代码。

这个 SO question "Where to put Django startups code?" 建议使用 AppConfig.ready 来启动代码。

但是,docs for the ready function 明确警告不要与数据库交互:

尽管您可以如上所述访问模型类,但请避免在您的 ready() 实现中与数据库交互。这包括执行查询的模型方法(save()、delete()、管理器方法等),以及通过 django.db.connection 进行的原始 SQL 查询。您的 ready() 方法将在每个管理命令的启动期间运行。例如,即使测试数据库配置与生产设置分开,manage.py test 仍会针对您的生产数据库执行一些查询!

对于需要更新数据库的代码,我应该使用一些稍后的启动挂钩吗?

代码将我的服务器注册为具有 3rd 方服务的 webhook 端点,并将所需的连接信息存储在数据库中。如果尚未配置,我只会注册 webhook。

【问题讨论】:

  • “启动”到底是什么意思? django 环境可以在多种情况下初始化——启动开发服务器、启动 wsgi worker、运行任何管理命令。
  • 您应该更具体地了解这段代码的作用。为什么你认为你需要在启动时更新数据库?
  • 我已经编辑了我的问题,以澄清我只需要在开发服务器和 wsgi 工作人员案例中运行代码。
  • 但肯定只需要ever为每一个发生一次,而不是每次启动服务器时。所以最好是作为一个管理命令,你可以在需要的时候运行。
  • @DanielRoseman,你提出了一个很好的观点。通常每个服务器只需要运行一次。我希望有一个比管理命令更自动化的解决方案。我有多个需要连接到 webhook 的服务器副本(测试、阶段、生产等)。管理命令是一个额外的步骤,有人最终会忘记让服务器脱离配置。

标签: django django-apps


【解决方案1】:

我们有一个类似的用例: 如果服务器重新启动,它需要管理数据库信息,以免某些程序处于停顿状态。

我们解决这个问题的方法是用一个systemd脚本,在启动时只执行一次,它调用一个脚本,在django的数据库中执行操作。

1) 创建一个 python 脚本,它将对数据库进行所需的操作和更改:

/djangoproject/boot_script.py

其中包含:

from yourdjangoapp.models import XModel
# DO STUFF WITH XModel

2) 为 django 创建一个调用 python 脚本的脚本:

/.../execute_boot_script.sh

其中包含:

cd /djangoproject
python manage.py shell < boot_script.py

并具有执行权:

sudo chmod +x /.../execute_boot_script.sh

3) 为服务创建文件:

/etc/systemd/system/execute_boot_script.service

其中包含:

[Unit]
After=apache2.service

[Service]
Environment=ENVPATH=:/usr/local/... # ONLY IF YOU NEED TO SET SOME ENVIRONMENT VARIABLE
Type=oneshot
ExecStart=/.../execute_boot_script.sh

[Install]
WantedBy=multi-user.target

更多信息: https://linuxconfig.org/how-to-automatically-execute-shell-script-at-startup-boot-on-systemd-linux

这个答案在 linux 中有效,但也可以在 windows 中通过启动时启动的编程任务轻松实现。

【讨论】:

    猜你喜欢
    • 2010-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-07
    • 2016-06-07
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    相关资源
    最近更新 更多