在python
開發(fā)中修改數(shù)據(jù)庫是常有的事情,今天和大家分享的就是定時(shí)修改數(shù)據(jù)庫那些事兒,希望對剛
入門python的童鞋有所幫助。
當(dāng)需要定時(shí)修改數(shù)據(jù)庫時(shí),一般我們都選擇起一個(gè)定時(shí)進(jìn)程去改庫。如果將這種定時(shí)任務(wù)寫入業(yè)務(wù)中,寫成一個(gè)接口呢,定時(shí)進(jìn)程顯得有些不太合適?如果需要定時(shí)修改100
次數(shù)據(jù)庫,常規(guī)做法會啟動
100
個(gè)進(jìn)程,雖然這種進(jìn)程非常輕量級,但還是會感覺不爽。實(shí)際上我們可以使用
threading.Timer
創(chuàng)建相應(yīng)的線程來執(zhí)行改庫操作,思路也比較簡單。
1.
傳入執(zhí)行改庫操作的時(shí)間
update_time
,用
update_time
和當(dāng)前時(shí)間相減法,得到距離改庫操作還有多少時(shí)間
time_delay
。求兩個(gè)標(biāo)準(zhǔn)時(shí)間格式字符串的時(shí)間差可以使用
datetime.datetime.strptime()
來格式化時(shí)間,格式化后的時(shí)間可以直接相減法,對結(jié)果執(zhí)行
.seconds()
就可以轉(zhuǎn)化成秒
2.
將改庫操作封裝成方法
update()
,然后將
update
和時(shí)間差傳入
threading.Timer
創(chuàng)建的線程,用法為
threading.Timer(interval, function, args=[], kwargs={})
創(chuàng)建線程實(shí)例,
interval
為延遲執(zhí)行的時(shí)間,單位是秒,然后
,start()
執(zhí)行。
Timer
是非阻塞的,可以創(chuàng)建出多個(gè)線程互不影響。
代碼如下
#!/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
改為前端傳入的參數(shù),就可以在該時(shí)間執(zhí)行改庫操作了。當(dāng)時(shí)遇到了一個(gè)小坑,就是改庫操作沒有生效,原因是沒加最后一行的
commit()
。本來改庫的
commit
生效是寫在基類
BaseHandler
重的,但是這里的
update()
在
Timer
線程中執(zhí)行,屬于異步操作,需要在線程中執(zhí)行
commit()
使改動生效。
這種借助Timer
定時(shí)執(zhí)行的方法比傳統(tǒng)的定時(shí)進(jìn)程更輕量,也更簡單,但是也有著明顯的缺點(diǎn)。當(dāng)服務(wù)關(guān)閉時(shí),所有的定時(shí)線程也就隨著主進(jìn)程一起銷毀,所有線程都能成功執(zhí)行的前提條件是服務(wù)必須穩(wěn)定,不能重啟。如果想要重啟服務(wù),就需要想辦法將未完成的任務(wù)落盤
(
比如寫到數(shù)據(jù)庫中
)
,然后啟動服務(wù)時(shí)讀取之前未完成的任務(wù)重新創(chuàng)建定時(shí)線程。
來源:網(wǎng)絡(luò)