如何从预定脚本访问Django模型?

2024-04-26 05:01:04 发布

您现在位置:Python中文网/ 问答频道 /正文

TL;DR:

我有一个应用程序,我想在每天午夜运行一个例程(为此,我使用APScheduler)。在这个例程的中间,它应该访问一些django模型的数据。你知道吗

逻辑是

Django is running > run apps.py > run scheduler.py > run routine.py > access models.py.

在文章底部提出的例外情况。你知道吗

-详情如下:

我的目录是:

myproject/
- manage.py

+ myproject/
-- settings.py
-- wsgi.py
-- ...

+ myapp/
-+ static/
-+ templates/
-- admin.py
-- apps.py
-- models.py
-- views.py
-- scheduler.py  #<<<<<<<<<<
-- routine.py    #<<<<<<<<<<
-- ...

我的应用程序/型号.py

class MyModel(models.Model):
    field1 = models.DateField(auto_now=True)
    field2 = models.DecimalField(max_digits=19, decimal_places=16)
    ...

我的应用程序/应用程序.py

from django.apps import AppConfig
from .scheduler import ScheduledRoutine

class MyAppConfig(AppConfig):
    name = 'myapp'

    def ready(self):
        routine = ScheduledRoutine()
        routine.start()

我的应用程序/调度程序.py

from .routine import MyRoutine
#from ..routine import MyRoutine   # See error nr3 <<<<<<<<<
from apscheduler.schedulers.background import BackgroundScheduler

class ScheduledRoutine(object):

    def start(self):
        self.scheduler = BackgroundScheduler()
        startdate = datetime.now() #For brevity assume datetime object
        self.scheduler.add_job(self.routine, 'interval', days=1, start_date=startdate)
        self.scheduler.start()

    def routine(self):
        data = MyRoutine()

我的应用程序/例行.py

import os
os.environ["DJANGO_SETTINGS_MODULE"] = "myproject.settings"
import django
django.setup()

from .models import MyModel
#from myapp.models import MyModel  # See error nr3 <<<<<<<<<

class MyRoutine(object):
    def __init__(self, arg):
        self.arg = arg
        data = MyModel.objects.filter(reliable=True)
        self.do_something(data)

-例外和什么不起作用

我已经试过几件事了,这些是我记得的:

-错误Nr1:

就目前的情况而言(如上所示),这是一个错误:

Watching for file changes with StatReloader
Exception in thread django-main-thread:
Traceback (most recent call last):
  File "C:\Python\Python37\lib\threading.py", line 917, in _bootstrap_inner
    self.run()
  File "C:\Python\Python37\lib\threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "C:\venv\lib\site-packages\django\utils\autoreload.py", line 54, in wrapper
    fn(*args, **kwargs)
  File "C:\venv\lib\site-packages\django\core\management\commands\runserver.py", line 109, in inner_run
    autoreload.raise_last_exception()
  File "C:\venv\lib\site-packages\django\utils\autoreload.py", line 77, in raise_last_exception
    raise _exception[1]
  File "C:\venv\lib\site-packages\django\core\management\__init__.py", line 337, in execute
    autoreload.check_errors(django.setup)()
  File "C:\venv\lib\site-packages\django\utils\autoreload.py", line 54, in wrapper
    fn(*args, **kwargs)
  File "C:\venv\lib\site-packages\django\__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "C:\venv\lib\site-packages\django\apps\registry.py", line 91, in populate
    app_config = AppConfig.create(entry)
  File "C:\venv\lib\site-packages\django\apps\config.py", line 90, in create
    module = import_module(entry)
  File "C:\Python\Python37\lib\importlib\__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "C:\venv\myproject\myapp\apps.py", line 2, in <module>
    from .scheduler import ScheduledRoutine
  File "C:\venv\myproject\myapp\scheduler.py", line 6, in <module>
    from .routine import MyRoutine
  File "C:\venv\myproject\myapp\routine.py", line 10, in <module>
    django.setup()
  File "C:\venv\lib\site-packages\django\__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "C:\venv\lib\site-packages\django\apps\registry.py", line 83, in populate
    raise RuntimeError("populate() isn't reentrant")
RuntimeError: populate() isn't reentrant

-错误Nr2:

因为routine.pymyapp/文件夹中,它试图引用myproject/settings.py,所以我尝试将.(也尝试了..)添加到引用中,如下所示:

os.environ["DJANGO_SETTINGS_MODULE"] = ".myproject.settings"

还有这个:

os.environ["DJANGO_SETTINGS_MODULE"] = "..myproject.settings"

两者都返回相同的异常:

TypeError: the 'package' argument is required to perform a relative import for '.myproject.settings'

-错误Nr3:

由于上面提到的相同问题(引用settings.pymyproject/settings.py),我尝试将routine.py移动到父文件夹,因此我需要将routine.pyscheduler.py中的导入更改为它们的注释版本。导致了这个例外:

ValueError: attempted relative import beyond top-level package

-错误Nr4:

另外,运行django时,注释了以下行(在例行.py)你知道吗

#os.environ["DJANGO_SETTINGS_MODULE"] = "myproject.settings"
#import django
#django.setup()

这几乎就是事情的开始。你知道吗

编辑: -错误Nr5: 在中使用此例行.py引发与Nr1相同的错误。你知道吗

from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
application = get_wsgi_application()

对我来说,问题显然是我试图访问routine.py中的模型的方式,而不是调度程序。我还能试什么?


Tags: djangoinfrompyimportselfsettingsvenv
1条回答
网友
1楼 · 发布于 2024-04-26 05:01:04

您可以尝试创建一个Django custom command,这样您就可以创建一个类似python manage.py myroutine的命令,并使用一个调度程序(比如cron)来运行它。如果这样做,可以避免代码中的所有这些:

os.environ["DJANGO_SETTINGS_MODULE"] = "myproject.settings"
import django
django.setup()

我知道这并不能完全解决你的问题,但这是一个解决办法。你知道吗

相关问题 更多 >