【问题标题】:Django: Run a script right after runserverDjango:在 runserver 之后立即运行脚本
【发布时间】:2019-06-11 06:42:07
【问题描述】:

上下文:

我有一个使用外部数据库值的数据库表。此外部数据库会定期更新其值。

问题:

为了在每次启动服务器时更新我的​​数据库,我想在运行服务器之后立即运行一个脚本。

潜在解决方案:

我已经看到可以从某个应用程序运行脚本,这是我感兴趣的事情。这可以通过使用 django-extensions 来实现:

https://django-extensions.readthedocs.io/en/latest/runscript.html

但是,此脚本只能使用以下命令运行:

python manage.py runscript your_script

有没有其他方法可以从应用程序运行脚本并在 runserver 命令之后立即执行它?我愿意接受建议!

提前致谢

更新

感谢@Raydel Miranda 的评论,我觉得我留下了一些信息。

我的目标是,一旦我启动服务器,我打算打开一个套接字来维护我的数据库更新。

【问题讨论】:

  • 你所要做的就是在你的url之后调用脚本。
  • 如果外部数据库定期更新,请查看我的解决方案,您不想为了获取新数据而定期重新启动服务器。使用多个数据库来实现您想要的。

标签: python django django-settings


【解决方案1】:

在 runserver 之后运行脚本似乎不是一个好主意,主要原因是您将有一个窗口,因为服务器正在运行(并且可供用户使用),直到您完成同步数据。此外,如果您在 runserver 之后使用脚本进行同步,之后您将无法从外部数据库获取更新。

最好的解决方案是配置多个数据库,您可以使用只有读取权限的外部数据库。这样,您的视图将提供真正更新的数据。

另一方面...

如果想使用类似脚本的东西最好写一个Django custom command(这样你就不必处理初始化django设置和其他问题)并使用cron或celery执行它,就像@ruddra在他/她的回答。

说了这个,你应该看到这个:https://docs.djangoproject.com/en/2.1/topics/db/multi-db/

【讨论】:

  • 感谢您的提示!实际上,我没有完全访问远程数据库的权限。我只能通过请求一个周期范围内的历史数据来获取一些值。我的目标是首先更新我的数据库,然后打开一个套接字来实时读取远程数据库
  • 查看答案中的“另一方面...”部分。
  • 我实现了 custom_command 并且工作正常!但是,我不能仅从 runserver 运行它
  • 再想一想我的朋友,你想使用 cron 运行这样的命令,比如说,每 5 分钟一次以保持你的数据更新。不仅在启动服务器时。
  • 正如第一条评论中所写,我不需要再次更新服务器,因为初始化后,我将打开一个套接字 (channels.readthedocs.io/en/latest)。
【解决方案2】:

我建议使用这样的东西,假设你有这样的脚本:

# abc.py

from your_app.models import do_something

do_something()

现在您可以在 runserver(或您运行 django 应用程序的任何其他方式)之后立即运行此脚本,如下所示:

python manage.py runserver & python manage.py shell < abc.py

仅供参考,只有在您的终端中安装了 bash(例如在 Linux、MacO 中)时,它才会起作用。

更新

仔细阅读您的问题后,我认为在runserver 之后运行脚本可能不是最好的解决方案。正如你所说:

此外部数据库会定期更新其值。

所以,我认为您需要某种定期任务来执行此更新。您可以使用cronjob 或使用Celery

【讨论】:

  • 我们可以为此投票给 cronjob,因为设置 Celery 对于单个 scipt 来说可能很昂贵
  • A custom Django command + cron 似乎是最简单的解决方案。脚本必须处理 django 设置初始化、路径等...
【解决方案3】:

This 可能会有所帮助。 你可以编辑 yourapp/apps.py

class MyAppConfig(AppConfig):
    name = 'myapp'

    def ready(self):
        # update my database here
        pass

【讨论】:

  • @Alvaro Again 这样的解决方案只会在您的服务器启动时更新您的数据一次。您希望让您的用户保持最新状态。
【解决方案4】:

您可以执行顶级urls.py 中的代码。该模块被导入并执行一次。

urls.py

from django.confs.urls.defaults import *
from your_script import one_time_startup_function

urlpatterns = ...

one_time_startup_function()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-18
    • 2015-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-31
    • 2011-09-16
    相关资源
    最近更新 更多