flask_apscheduler 定时任务踩坑记录

背景

由于需要再flask做一个定时任务,然后发现了这个库flask_apscheduler.使用很简单,就是可能由于某种情况,会有一些意外,下面是我的使用记录。

首先按照官方文档跑一个示例
from flask import Flask
from flask_apscheduler import APScheduler


class Config(object):
    JOBS = [
        {
            'id': 'job1',
            'func': 'jobs:job1',
            'args': (1, 2),
            'trigger': 'interval',
            'seconds': 10
        }
    ]

    SCHEDULER_API_ENABLED = True


def job1(a, b):
    print(str(a) + ' ' + str(b))


if __name__ == '__main__':
    app = Flask(__name__)
    app.config.from_object(Config())

    scheduler = APScheduler()
    # it is also possible to enable the API directly
    # scheduler.api_enabled = True
    scheduler.init_app(app)
    scheduler.start()

    app.run()
  • 'func': 'jobs:job1', 配置文件中这一行,代表任务。jobs代表这个文件名。job1是自己创建的任务函数。

ok,这里没有任何问题

问题1:在实际项目中,不可能都放在同一个文件下,创建一个任务时,找不到这个任务

如,我定义一个start函数,用于执行定时任务,这个start在app.models.ali路径下。问题原因是:'func': 'app:start'配置格式等有误,正确应该按照自己任务文件的实际路径,格式为:'func': 'app:models.ali.start',如下:

class Config:

    JOBS = [
        {
            'id': 'job1',
            'func': 'app:models.ali.start',
            'trigger': 'cron',
            'day_of_week': 'mon-fri',
            'second': 1,
            'hour': 9,
            'minute': 30
        }
    ]

    SCHEDULER_API_ENABLED = True
问题2:在model文件里使用SQLAlchemy时,报错类似:No application found.flask-apsched Either work inside a view function or pus,也就是无法在任务函数中使用SQLAlchemy。解决办法:
  • app的__init__.py关键代码:
from flask_apscheduler import APScheduler
scheduler = APScheduler()

def create_app(config_name):
    app = Flask(__name__, template_folder='templates')
    app.config.from_object(config.get(config_name) or config['default'])
    ...
    scheduler.init_app(app)
    scheduler.start()
    return app

  • 然后我的任务start在app.models.ali路径下,需要在ali.py下:
from app import scheduler

def start():
    with scheduler.app.app_context():
        results = AliServers.query.all()
        ···

添加上下文后,就可以使用AliServers.query.all()这种操作了。

问题3:

本机开发环境下,一切正常,然后部署到服务器上,出错:

Traceback (most recent call last):
  File "test.py", line 29, in <module>
    scheduler = APScheduler()
  File "/root/.local/share/virtualenvs/flask-fUo2koNK/lib/python3.6/site-packages/flask_apscheduler/scheduler.py", line 36, in __init__
    self._scheduler = scheduler or BackgroundScheduler()
  File "/root/.local/share/virtualenvs/flask-fUo2koNK/lib/python3.6/site-packages/apscheduler/schedulers/base.py", line 87, in __init__
    self.configure(gconfig, **options)
  File "/root/.local/share/virtualenvs/flask-fUo2koNK/lib/python3.6/site-packages/apscheduler/schedulers/base.py", line 126, in configure
    self._configure(config)
  File "/root/.local/share/virtualenvs/flask-fUo2koNK/lib/python3.6/site-packages/apscheduler/schedulers/background.py", line 29, in _configure
    super(BackgroundScheduler, self)._configure(config)
  File "/root/.local/share/virtualenvs/flask-fUo2koNK/lib/python3.6/site-packages/apscheduler/schedulers/base.py", line 697, in _configure
    self.timezone = astimezone(config.pop('timezone', None)) or get_localzone()
  File "/root/.local/share/virtualenvs/flask-fUo2koNK/lib/python3.6/site-packages/tzlocal/unix.py", line 165, in get_localzone
    _cache_tz = _get_localzone()
  File "/root/.local/share/virtualenvs/flask-fUo2koNK/lib/python3.6/site-packages/tzlocal/unix.py", line 90, in _get_localzone
    utils.assert_tz_offset(tz)
  File "/root/.local/share/virtualenvs/flask-fUo2koNK/lib/python3.6/site-packages/tzlocal/utils.py", line 38, in assert_tz_offset
    raise ValueError(msg)
ValueError: Timezone offset does not match system offset: 28800 != -14400. Please, check your config files.

根据错误信息查看源码,解决办法:
主要是两个地方:
首先查看服务器时区是上海,然后需要修改两个地方:

  • 在配置文件中添加SCHEDULER_TIMEZONE = 'Asia/Shanghai',即:
class Config:

    JOBS = [
        {
            'id': 'job1',
            'func': 'app:models.ali.start',
            'trigger': 'cron',
            'day_of_week': 'mon-fri',
            'second': 1,
            'hour': 9,
            'minute': 30
        }
    ]
    SCHEDULER_TIMEZONE = 'Asia/Shanghai'
    SCHEDULER_API_ENABLED = True

然后在app的__init__.py下,添加BackgroundScheduler(timezone="Asia/Shanghai")

from flask_apscheduler import APScheduler
from apscheduler.schedulers.background import BackgroundScheduler 
scheduler = APScheduler(BackgroundScheduler(timezone="Asia/Shanghai"))

def create_app(config_name):
    app = Flask(__name__, template_folder='templates')
    app.config.from_object(config.get(config_name) or config['default'])
    ...

    scheduler.init_app(app)
    scheduler.start()
    return app

原因是:时区会被解析两次,如果没有加时区,就会调用默认的self.timezone = astimezone(config.pop('timezone', None)) or get_localzone(),由于时区与系统不匹配,会报错。当然这个错误并不是每个机器都有,正巧,这台服务器的时区与系统偏移不一致,导致出现这个错误。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容