2016-11-17 15 views
2

Привет, сообщество stackoverflow, у меня возникла проблема с расписанием задания cron, которое требует соскабливания веб-сайта и хранения его как части модели (MOVIE) в базе данных. Проблема в том, что модель, кажется, загружается до запуска Procfile. Как мне создать задание cron, которое выполняется внутри фона и хранит очищенную информацию в базе данных? Вот мои коды:ВОПРОСЫ Определение заданий Cron в Procfile (Heroku) с использованием apscheduler для проекта Django

PROCFILE:

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 

from django.db import models 

кинотеатры/models.py:

#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]: import cineplex 2016-11-17T17: 57: 06.075060+ 00:00 app [scheduler.1]: Файл «/app/cinemas/cineplex.py», строка 1, в 2016-11-17T17: 57: 06.075173 + 00: 00 приложение [scheduler.1]: из кинотеатров. моделирование импорта 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]: класс Movie (models.Model): 2016-11-17T17: 57: 06.075297 + 00: 00 app [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_containing_app_config (модуль) 2016-11-17T17: 57: 06.075440 + 00: 00 app [scheduler.1]: Файл «/app/.heroku/python/lib/python3. 5/site-packages/django/apps/registry.py ", строка 237, в get_containing_app_config 2016-11-17T17: 57: 06.075585 + 00: 00 app [scheduler.1]: self.check_apps_ready() 2016-11 -17T17: 57: 06.075586 + 00: 00 app [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]: повысить AppRegistryNotReady («Приложения еще не загружены») 2016-11-17T17: 57: 06.075726 + 00: 00 приложение [сч eduler.1]: django.core.exceptions.AppRegistryNotReady: приложения еще не загружены.

Работа в Cron отлично работает, если я не включаю объекты модели. Как я должен запускать эту работу каждый день, используя объекты модели без сбоев?

Благодаря

ответ

2

Это потому, что вы не можете просто импортировать пакеты Django, модели и т.д .; для правильной работы внутренние элементы Django требуют инициализации, которая запускается с manage.py. Вместо того, чтобы пытаться и воссоздавать все это самостоятельно, я всегда пишу долговременные, не-веб-команды в качестве настраиваемой команды управления (см. https://docs.djangoproject.com/en/1.10/howto/custom-management-commands/). Например, если ваше приложение cinemas, вы бы:

  • Создать ./cinemas/management/commands/scheduler.py.
  • В этом файле подклассу django.core.management.base.BaseCommand (что суб-класс должен быть назван Command)
  • В этом классе переопределить handle().В вашем случае, это где вы бы назвали sched.start()
  • Ваш Procfile бы тогда scheduler: python manage.py scheduler

Надежда, что помогает.

+0

Спасибо! Это работает для меня :) –

0

Вы можете решить эту проблему с добавлением следующих строк в верхней части sceduler.py

import django 
django.setup() 

В документации Джанго it says

Если вы используете компоненты Django «автономный »- например, написав скрипт Python, который загружает некоторые шаблоны Django и отображает их, или использует 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 в качестве переменной конфигурации так и не добавить его в мой планировщик.