具体来说,如何
- 在 Django 项目中设置APScheduler
- 开始跑步
- 写给 Django ORM
好吧,我会去的。假设您已经安装了 apscheduler(或将其放在 Python 路径中)APS 的基本文档列出了以下用于启动作业的代码:
from apscheduler.scheduler import Scheduler
sched = Scheduler()
@sched.interval_schedule(hours=3)
def some_job():
print "Decorated job"
sched.configure(options_from_ini_file)
sched.start()
我怀疑你遇到的问题是如何在 Django 中触发它的启动。您有多种选择,主要包括“将其放在将运行的地方”。例如,将其添加到models.py
文件的底部,或者添加到文件中,urls.py
每次 Django 重启时都会处理一次,然后继续在后台运行。然后可以从函数中正常执行数据库访问 - 只需正常导入模型以进行查询。
但是,请考虑如果您这样做,您将需要在您想要更改调度的任何时候终止并重新启动您的服务器。我也不确定这将如何处理多个线程(你会有> 1个计时器吗?)
你真的可能想考虑使用像Celery(通过django-celery)这样的东西,它可以让你获得所有这些,加上一个单独的调度守护进程,可以更好地控制调度。
要使用这个 apscheduler,您可以使用下面的代码进行设置,唯一可能遇到困难的部分是使用 jobstore sqlalchemy
,但由于您已经有一个 django ORM,它也可以工作。
from apscheduler.schedulers.background import BackgroundScheduler
scheduler = BackgroundScheduler()
scheduler.start()
def myjob():
print('hello')
scheduler.add_job(myjob, 'cron', hour=0)
scheduler.add_job(
myjob,
'date',
id=id_value,
jobstore="default",
run_date=scheduler_date,
replace_existing=True
)
我建议使用:django-apscheduler,它已经与带有 DjangoORM 的 jobstore 集成,并且还提供了一个 Web 界面来管理作业
对于 django-apscheduler,可以使用下面的代码
import time
from apscheduler.schedulers.background import BackgroundScheduler
from django_apscheduler.jobstores import DjangoJobStore, register_events,
register_job
scheduler = BackgroundScheduler()
scheduler.add_jobstore(DjangoJobStore(), "default")
@register_job(scheduler, "interval", seconds=1)
def test_job():
time.sleep(4)
print("I'm a test job!")
# raise ValueError("Olala!")
register_events(scheduler)
scheduler.start()
print("Scheduler started!")
试试下面的代码。
project name
:crawling_server
django-admin startproject crawling_server
cd crawling_server
app name
:stock_crawling
python manage.py startapp stock_crawling
purpose
: 每秒打印 'hello world'
pip install -r requirements.txt
APScheduler==3.8.1
asgiref==3.4.1
backports.zoneinfo==0.2.1
beautifulsoup4==4.10.0
certifi==2021.10.8
Django==3.2.10
django-apscheduler==0.6.0
pytz==2021.3
pytz-deprecation-shim==0.1.0.post0
six==1.16.0
soupsieve==2.3.1
sqlparse==0.4.2
typing_extensions==4.0.1
tzdata==2021.5
tzlocal==4.1
在下面添加代码settings.py
INSTALLED_APPS = [
...
'stock_crawling',
'django_apscheduler',
]
APSCHEDULER_DATETIME_FORMAT = "N j, Y, f:s a" # Default
SCHEDULER_DEFAULT = True
在下面添加代码views.py
import datetime
def send_hello():
time = datetime.datetime.now()
print('hello world:[{}]'.format(time))
在项目目录中生成operator.py
(见下面的目录树)
./
├── crawling_server <- **project dir**
│ ├── asgi.py
│ ├── operator.py <- **generate this script**
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── db.sqlite3
├── manage.py
├── requirements.txt
└── stock_crawling
├── admin.py
├── apps.py
├── migrations
├── models.py
├── tests.py
└── views.py
在下面添加代码operator.py
from apscheduler.schedulers.background import BackgroundScheduler
from django_apscheduler.jobstores import register_events, DjangoJobStore
from stock_crawling.views import send_hello
def start():
scheduler = BackgroundScheduler()
scheduler.add_jobstore(DjangoJobStore(), 'djangojobstore')
register_events(scheduler)
@scheduler.scheduled_job('interval', seconds=1, name='auto_hello')
def auto_hello():
send_hello()
scheduler.start()
间隔 或cron用作调度程序触发器。有关详细信息,请参阅下面的链接。
示例间隔触发器
@scheduler.scheduled_job('interval', seconds=1, name='auto_hello')
示例cron触发器
@scheduler.scheduled_job('cron', hour=1, name='auto_hello')
app.py
在项目目录中添加以下代码
from django.apps import AppConfig
from django.conf import settings
class StockCrawlingConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'stock_crawling'
def ready(self):
if settings.SCHEDULER_DEFAULT:
from crawling_server import operator
operator.start()
python manage.py runserver --noreload
hello world:[2021-12-13 12:34:33.982562]
Job '259a33f9664248bea607aa9ba0cdd587' no longer exists! Skipping logging of job execution...
Job '259a33f9664248bea607aa9ba0cdd587' no longer exists! Skipping logging of job execution...
hello world:[2021-12-13 12:34:34.982743]
Job '259a33f9664248bea607aa9ba0cdd587' no longer exists! Skipping logging of job execution...
Job '259a33f9664248bea607aa9ba0cdd587' no longer exists! Skipping logging of job execution...
hello world:[2021-12-13 12:34:35.986722]