APScheduler提供了基于日期、固定时间间隔以及crontab类型的任务,并且可以持久化任务。
APScheduler提供了多种不同的调度器,方便开发者根据自己的实际需要进行使用;同时也提供了不同的存储机制,可以方便与Redis,数据库等第三方的外部持久化机制进行协同工作,总之功能非常强大和易用。
APScheduler的主要的调度类
在APScheduler中有以下几个非常重要的概念,需要大家理解:
触发器(trigger)
包含调度逻辑,每一个作业有它自己的触发器,用于决定接下来哪一个作业会运行,根据trigger中定义的时间点,频率,时间区间等等参数设置。除了他们自己初始配置以外,触发器完全是无状态的。
作业存储(job store)
存储被调度的作业,默认的作业存储是简单地把作业保存在内存中,其他的作业存储是将作业保存在数据库中。一个作业的数据讲在保存在持久化作业存储时被序列化,并在加载时被反序列化。调度器不能分享同一个作业存储。job store支持主流的存储机制:redis, mongodb, 关系型数据库, 内存等等
执行器(executor)
处理作业的运行,他们通常通过在作业中提交制定的可调用对象到一个线程或者进城池来进行。当作业完成时,执行器将会通知调度器。基于池化的操作,可以针对不同类型的作业任务,更为高效地使用cpu的计算资源。
调度器(scheduler)
通常在应用只有一个调度器,调度器提供了处理这些的合适的接口。配置作业存储和执行器可以在调度器中完成,例如添加、修改和移除作业。
这里简单列一下常用的若干调度器:
BlockingScheduler:仅可用在当前你的进程之内,与当前的进行共享计算资源
BackgroundScheduler: 在后台运行调度,不影响当前的系统计算运行
AsyncIOScheduler: 如果当前系统中使用了async module,则需要使用异步的调度器
GeventScheduler: 如果使用了gevent,则需要使用该调度
TornadoScheduler: 如果使用了Tornado, 则使用当前的调度器
TwistedScheduler:Twister应用的调度器
QtScheduler: Qt的调度器
import time
import datetime
def job_function(id,iid,uid,user_id,repay_time,month):
# 当前时间+预期时间 是否大于数据库时间
times = time.mktime(time.strptime(month, "%Y-%m-%d"))
if times-time.time() !=0:
months = get_Month(datetime.datetime.strptime(month, '%Y-%m-%d'),'-',1)
monthss = time.mktime(time.strptime(months, "%Y-%m-%d"))
if time.time() == monthss:
# months =
# 根据发标id 去投资表中进行查找type 为0 未投资的人数
sql = "select * from investment_order where capital_id=%d and type=0"%(int(id))
res = db.find(sql)
# 算出 投资金额+利率
nums = float(res['money']) * float(res['interest'])
# 自动扣除发标用户金额
sql1 = "select money,actual_money from user where id=%d"%(int(user_id))
res1 = db.find(sql1)
money = float(res1['money']) - float(nums)
# 更改发标用户中金额
sql4 = "update user set money=%.2f,actual_money=%.2f where id=%d"%(float(money),float(money),int(user_id))
# 自动增加投标用户金额
sql2 = "select money,actual_money from user where id=%d" % (int(uid))
res2 = db.find(sql2)
money = float(res2['money']) + float(nums)
# 更改发标用户中金额
sql3 = "update user set money=%.2f,actual_money=%.2f where id=%d" % (float(money), float(money), int(uid))
# 根据投标表id 去查询投资记录表中记录的capital_id查询 type状态是否为1已还款 ,
# try:
# 更改完用 则更改投标状态为1
sql5 = "update investment_order set type=1 where capital_id=%d and user_id=%d and id=%d" % (
int(id), int(uid), int(iid))
db.add(sql4)
db.add(sql3)
db.add(sql5)
# 如果记录都为1,将投资表中状态改为8已完成
sql6 = "select count(type) as type from investment_order where capital_id=%d and user_id=%d and type=0" % (
int(iid), int(uid))
res6 = db.findall(sql6)
for i in res6:
if i['type'] == 0:
# 修改投资表中状态为8
sql7 = "update capital set status=8 where id=%d" % (int(id))
db.add(sql7)
else:
break
db.commit()
return jsonify({'code': 200, 'msg': '还款成功'})
# except :
# db.rollback()
# return jsonify({'code': 403, 'msg': '还款失败'})
else:
pass
else:
pass
from apscheduler.schedulers.background import BackgroundScheduler
def test1():
sched = BackgroundScheduler()
# 查询为还款的信息
sql = "select c.id,c.starttime,c.repay_time,c.user_id,i.user_id as uid,i.id as iid from capital as c inner join investment_order as i on c.id=i.capital_id where c.status=7"
res = db.findall(sql)
if res:
# 添加调度任务
for i in res:
month = get_Month(i['starttime'], '+', i['repay_time'])
# 调度方法为 timedTask,触发器选择 interval(间隔性),间隔时长为 2 秒
# sched.add_job(job_function, 'interval', seconds=2, args=[i['id'],i['iid'],i['uid'],i['user_id'],i['repay_time'],month])
# sched.add_job(job_function, 'cron',month=int(i['repay_time'])-1, hour=0, minute=30,args=[i['id'],j['iid'],j['uid'],i['user_id'],month])
# 每天00:30执行
sched.add_job(job_function, 'cron', day_of_week='*', hour=0, minute=30,args=[i['id'],i['iid'],i['uid'],i['user_id'],i['repay_time'],month])
# 启动调度任务
sched.start()
return 'ok'
else:
pass