【问题标题】:ISSUES Defining Cron jobs in Procfile (Heroku) using apscheduler for Django project问题使用 Django 项目的 apscheduler 在 Procfile (Heroku) 中定义 Cron 作业
【发布时间】:2017-04-01 09:57:54
【问题描述】:

我在安排 cron 作业时遇到问题,该作业需要抓取网站并将其作为模型 (MOVIE) 的一部分存储在数据库中。

问题是模型似乎在 Procfile 执行之前被加载。
我应该如何创建一个在后台内部运行并将抓取的信息存储到数据库中的 cron 作业?这是我的代码:

过程文件:

    web: python manage.py runserver 0.0.0.0:$PORT
    scheduler: python cinemas/scheduler.py

scheduler.py:

# More code above
from cinemas.models import Movie
from apscheduler.schedulers.blocking import BlockingScheduler
sched = BlockingScheduler()

@sched.scheduled_job('cron', day_of_week='mon-fri', hour=0, minutes=26)    
def get_movies_playing_now():
  global url_movies_playing_now
  Movie.objects.all().delete()
  while(url_movies_playing_now):
    title = []
    description = []
    #Create BeatifulSoup Object with url link
    s = requests.get(url_movies_playing_now, headers=headers)
    soup = bs4.BeautifulSoup(s.text, "html.parser")
    movies = soup.find_all('ul', class_='w462')[0]

    #Find Movie's title
    for movie_title in movies.find_all('h3'):
        title.append(movie_title.text)
    #Find Movie's description
    for movie_description in soup.find_all('ul',
                                           class_='w462')[0].find_all('p'):
        description.append(movie_description.text.replace(" [More]","."))

    for t, d in zip(title, description):
        m = Movie(movie_title=t, movie_description=d)
        m.save()

    #Go to the next page to find more movies
    paging = soup.find( class_='pagenating').find_all('a', class_=lambda x:
                                                      x != "inactive")
    href = ""
    for p in paging:
        if "next" in p.text.lower():
            href = p['href']
    url_movies_playing_now = href

sched.start()
# More code below

电影院/models.py:

from django.db import models

#Create your models here.

class Movie(models.Model):
    movie_title = models.CharField(max_length=200)
    movie_description = models.CharField(max_length=20200)

这是我在运行作业时遇到的错误。

2016-11-17T17:57:06.074914+00:00 app[scheduler.1]: Traceback(最 最近通话最后):2016-11-17T17:57:06.074931+00:00 app[scheduler.1]: 文件“cinemas/scheduler.py”,第 2 行,在 2016-11-17T17:57:06.075058+00:00 应用程序 [scheduler.1]:导入电影院 2016-11-17T17:57:06.075060+00:00 应用程序 [scheduler.1]:文件 “/app/cinemas/cineplex.py”,第 1 行,在 2016-11-17T17:57:06.075173+00:00 应用程序 [scheduler.1]:来自 Cinemas.models 导入电影 2016-11-17T17:57:06.075196+00:00 app[scheduler.1]:文件“/app/cinemas/models.py”,第 5 行,在 2016-11-17T17:57:06.075295+00:00 应用程序 [scheduler.1]: 类 电影(models.Model): 2016-11-17T17:57:06.075297+00:00 应用程序 [scheduler.1]:文件 “/app/.heroku/python/lib/python3.5/site-packages/django/db/models/base.py”, 第 105 行,在 2016-11-17T17:57:06.075414+00:00 app[scheduler.1]: app_config = apps.get_ contains_app_config(模块) 2016-11-17T17:57:06.075440+00:00 应用程序 [scheduler.1]:文件 "/app/.heroku/python/lib/python3.5/site-packages/django/apps/registry.py", 第 237 行,在 get_ contains_app_config 中 2016-11-17T17:57:06.075585+00:00 应用[scheduler.1]:
self.check_apps_ready() 2016-11-17T17:57:06.075586+00:00 应用程序 [scheduler.1]:文件 "/app/.heroku/python/lib/python3.5/site-packages/django/apps/registry.py", 第 124 行,在 check_apps_ready 2016-11-17T17:57:06.075703+00:00 app[scheduler.1]: raise AppRegistryNotReady("应用未加载 还。”)2016-11-17T17:57:06.075726+00:00 应用程序 [scheduler.1]: django.core.exceptions.AppRegistryNotReady:应用尚未加载。

如果我不包含模型对象,Cron 作业可以正常工作。我应该如何每天使用模型对象运行这项工作而不会失败?

谢谢

【问题讨论】:

    标签: python django heroku cron apscheduler


    【解决方案1】:

    这是因为您不能只导入 Django 包、模型等。
    为了正常工作,Django 内部需要初始化,这是从manage.py 触发的。

    我总是将长时间运行的非网络命令编写为custom management command,而不是尝试自己重新创建所有内容。

    例如,如果你的应用是cinemas,你会:

    • 创建./cinemas/management/commands/scheduler.py
    • 在该文件中,创建一个子类django.core.management.base.BaseCommand(该子类必须称为Command
    • 在该类中,覆盖handle()。就你而言,这就是你打电话给sched.start()的地方
    • 您的Procfile 将拥有scheduler: python manage.py scheduler

    希望对您有所帮助。

    【讨论】:

      【解决方案2】:

      您可以在 sceduler.py 的顶部添加以下行来解决问题

      import django
      django.setup()
      

      在 django 文档中it says

      如果您正在使用“独立”的 Django 组件——例如,编写一个加载一些 Django 模板并呈现它们的 Python 脚本,或者使用 ORM 来获取一些数据——你还需要另外一个步骤配置设置。

      设置 DJANGO_SETTINGS_MODULE 或调用 configure() 后,您需要调用 django.setup() 来加载设置并填充 Django 的应用程序注册表。例如:

      import django
      from django.conf import settings
      from myapp import myapp_defaults
      
      settings.configure(default_settings=myapp_defaults, DEBUG=True)
      django.setup()
      
      # Now this script or any imported module can use any part of Django it needs.
      from myapp import models
      

      我将 DJANGO_SETTINGS_MODULE 设置为配置变量,因此没有将其添加到我的调度程序中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-28
        • 1970-01-01
        • 2017-04-02
        • 2018-03-09
        • 1970-01-01
        • 1970-01-01
        • 2023-04-07
        • 1970-01-01
        相关资源
        最近更新 更多