Swift51.com
麦子学院 头像
麦子学院  2018-04-11 22:53

Python学习之定时修改数据库详解

回复:0  查看:2680  
python 开发中修改数据库是常有的事情,今天和大家分享的就是定时修改数据库那些事儿,希望对刚 入门python的童鞋有所帮助。
  当需要定时修改数据库时,一般我们都选择起一个定时进程去改库。如果将这种定时任务写入业务中,写成一个接口呢,定时进程显得有些不太合适?如果需要定时修改100 次数据库,常规做法会启动 100 个进程,虽然这种进程非常轻量级,但还是会感觉不爽。实际上我们可以使用 threading.Timer 创建相应的线程来执行改库操作,思路也比较简单。
  1. 传入执行改库操作的时间 update_time ,用 update_time 和当前时间相减法,得到距离改库操作还有多少时间 time_delay 。求两个标准时间格式字符串的时间差可以使用 datetime.datetime.strptime() 来格式化时间,格式化后的时间可以直接相减法,对结果执行 .seconds() 就可以转化成秒
  2. 将改库操作封装成方法 update() ,然后将 update 和时间差传入 threading.Timer 创建的线程,用法为 threading.Timer(interval, function, args=[], kwargs={}) 创建线程实例, interval 为延迟执行的时间,单位是秒,然后 ,start() 执行。 Timer 是非阻塞的,可以创建出多个线程互不影响。
  代码如下
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
   from model  import Table from handler.base_handler  import BaseHandler from threading  import Timer import datetime
   class  TimeHandler(BaseHandler):
   def  do_action(self):
  update_time = "2018-04-07 18:00:00"
  ads_id = "test_1"
  t_online = datetime.datetime.strptime(update_time, '%Y-%m-%d %H:%M:%S')
  now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  t_now = datetime.datetime.strptime(now, '%Y-%m-%d %H:%M:%S')
  time_delay = (t_online - t_now).seconds
  t1 = Timer(time_delay, self.update, (ads_id, ))
  t1.start()
  self.result = "success"
   return
   def  update(self, ads_id):
  self.db.dsp.query(Table).filter(Table.ads_id == ads_id).update({Table.is_del: 0})
  self.db.dsp.commit()
  可以将update_time 改为前端传入的参数,就可以在该时间执行改库操作了。当时遇到了一个小坑,就是改库操作没有生效,原因是没加最后一行的 commit() 。本来改库的 commit 生效是写在基类 BaseHandler 重的,但是这里的 update() Timer 线程中执行,属于异步操作,需要在线程中执行 commit() 使改动生效。
  这种借助Timer 定时执行的方法比传统的定时进程更轻量,也更简单,但是也有着明显的缺点。当服务关闭时,所有的定时线程也就随着主进程一起销毁,所有线程都能成功执行的前提条件是服务必须稳定,不能重启。如果想要重启服务,就需要想办法将未完成的任务落盘 ( 比如写到数据库中 ) ,然后启动服务时读取之前未完成的任务重新创建定时线程。
来源:网络