Flask 中怎样用 while 写一个定时执行的任务?(定时查询最新数据)

2021-07-11 11:26:52 +08:00
 miniyao

用 before_app_first_request 的钩子,希望 app 首次启动时,开始运行一个每隔 1 小时定时查询最新数据的任务。结果发现这个任务每隔 1 小时去查询最新的数据,通过 flask_sqlalchemy 初始化之后的工厂模式,查询到的数据都是一样的。如下:


def async_cron_task(app):

with app.app_context():

while True:

new_user = User.query.order_by(User.reg_time.desc()).first()

print('New User: ', new_user.id)

time.sleep(3600)



def cron_task():

app = current_app._get_current_object()

thr = Thread(target=async_cron_task, args=[app])

thr.start()

return thr

但是,如果把数据库写成硬连接,就可以查到最新数据:


db = MySQLdb.connect(host='localhost', port=3306, user='xxx', passwd='xxx', db='xxx', charset='utf8')

cursor = db.cursor()

由于原生 SQL 查询语句太复杂了,希望用 SQLAlchemy 的方式连接数据库,要怎么样才能定时查到新数据呢?

4668 次点击
所在节点    Python
43 条回复
cz5424
2021-07-11 11:36:46 +08:00
Flask 不适合做定时,定时任务可以选择系统 crontab 执行脚本或者 celery
wellsc
2021-07-11 11:36:55 +08:00
我没看懂,写个异步任务脚本?
BingoXuan
2021-07-11 11:37:48 +08:00
轻量就用 huey 做异步队列
miniyao
2021-07-11 11:45:07 +08:00
@cz5424 后面我提到了,因为要写非常复杂的 sql 去查询数据、处理完了还要写回系统,系统 crontab 需要单独写不少代码。celery 用过,过了几个星期自动假死,不敢用了,没有 app 级的 while 可靠。

@wellsc 对,可以这么理解。异步任务中,写了一个死循环(定时任务)。
miniyao
2021-07-11 11:47:01 +08:00
@BingoXuan 就是不想用队列工具,增加一层不确定性。毕竟 app 级 while 很靠谱呀
cz5424
2021-07-11 11:49:53 +08:00
celery 并不是玩具,只是你不熟悉,实际上给的这些看不出你查询每次都一样的问题在哪里,可以尝试一下调换这两个的顺序

```python
with app.app_context():

while True:
```
miniyao
2021-07-11 12:04:02 +08:00
@cz5424 每次查询的数据都一样的意思是,就是无论系统有没有新赠的 new_user.id ,这里面 print 的 id 都不会变。感谢!上下调换了一下顺序,数据就可以更新了,应该是上下文没有切换。
MintZX
2021-07-11 14:04:34 +08:00
对啊,你这个明显是在同样的 context 里面空转啊。。。可不是每次获得的数据一样
knightdf
2021-07-11 15:23:27 +08:00
@miniyao celery 用过,过了几个星期自动假死,不敢用了,没有 app 级的 while 可靠。
自己写的有问题吧?我们线上产品都用了 celery,毛事没有
liuxingdeyu
2021-07-11 15:41:12 +08:00
我的思路是,定时任务、api 、各种 handler 自己干自己的,然后从启动命令里区分出来。如果需要通信就搞个消息通道。之前我们的项目就是一大坨面条似的东西,又弱又乱,后来我拆分出来 dao 层,把各种工具类还有枚举统一放,把 api 和定时任务拆开,各干各的。这样扩容也方便,自己查自己改也方便,容器化之后还能搞一堆镜像各用各的。flask 做定时任务除了 celery 我记得还有个 apscheduler,不过这东西贼坑,只能用线程( mokey_pach 后会切换失败)
ytmsdy
2021-07-11 15:43:16 +08:00
用 crontab,或者 celery 吧。
自己写太费劲了
yingxiangyu
2021-07-11 15:43:45 +08:00
celery+apscheduler
yingxiangyu
2021-07-11 15:44:53 +08:00
celery 定时任务不太好使,定时可以用 apscheduler 实现,触发任务 celery 异步执行
ila
2021-07-11 18:50:30 +08:00
用 mysql 的 event schedule
Hardrain
2021-07-11 20:47:13 +08:00
要定时执行的单独一个文件,建一个 oneshot 的 systemd service 配合 timer 就好了
cron 过时了
sunhk25
2021-07-11 21:13:01 +08:00
@miniyao celery 自动假死是指定期任务不执行吗?
hunk
2021-07-11 22:21:43 +08:00
Flask+ apscheduler
ch2
2021-07-11 23:15:59 +08:00
apscheduler 插件
triptipstop
2021-07-11 23:55:42 +08:00
crontab 怎么会多写代码?
http 接口写好,定时 get 一下就行。
kkx
2021-07-12 05:24:03 +08:00
crontab 需要多写很多代码说明你代码写的耦合度高。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/788811

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX