Python腳本實(shí)現(xiàn)自動(dòng)將數(shù)據(jù)庫(kù)備份到 Dropbox
最近,正好發(fā)生了一件大事,就是 GitLab 的運(yùn)維同學(xué)不小心刪除了生產(chǎn)的數(shù)據(jù),雖然 GitLab 已經(jīng)駭人聽(tīng)聞的準(zhǔn)備了五種備份機(jī)制,但是,仍然導(dǎo)致他們丟失了將近 6 個(gè)小時(shí)的用戶(hù)數(shù)據(jù),尤其對(duì)他們聲譽(yù)的損失,是根本無(wú)法估量的。反思一下,這個(gè)博客 Becomin' Charles,也是沒(méi)有完善的備份的,真是冷汗直冒啊,主要考慮到這是我的個(gè)人博客,但是想想已經(jīng)堅(jiān)持了快十年了,如果真的丟了的話(huà),還是非常痛心的。
正好,老婆最近正在學(xué)習(xí)Python 編程,我在教她,其實(shí),我是PHP 程序員,一點(diǎn)也不喜歡 Python,但是說(shuō)實(shí)在,一個(gè)外行學(xué)編程的話(huà),Python 確實(shí)比PHP 友好太多了,只能推薦她學(xué) Python 了。正好,借著這個(gè)機(jī)會(huì),我決定自己也學(xué)學(xué) Python 編程吧,于是,我決定要用 Python 做一個(gè)數(shù)據(jù)庫(kù)的自動(dòng)備份腳本。備份的位置,就用Dropbox 來(lái)做吧,因?yàn)槲业姆?wù)器是 Linode 提供的,美國(guó) fremont 機(jī)房,選擇美國(guó)的存儲(chǔ)服務(wù),比較合適。以下是我寫(xiě)得代碼,Python 小白,敬請(qǐng)指教:
#!/usr/bin/python #coding:utf-8 import sys import os from yamlimport load from datetime import datetime import dropbox from dropbox.filesimport WriteMode from dropbox.exceptions import ApiError, AuthError if len(sys.argv) < 2: print >>sys.stderr, "Usage: %s <config_file>" % sys.argv[0] sys.exit(0) conf = load(file(sys.argv[1], 'r')) # config file is a YAML looks like # --- # server-name: 127.0.0.1 # local-backup-path: /tmp # remote-backup-path: /backup # dropbox-token: jdkgjdkjg # databases: # - host: localhost # port: 3306 # user: user # pass: password # name: database1 # charset: utf8 # - host: localhost # port: 3306 # user: user2 # pass: password2 # name: database2 # charset: utf8 for dbin conf['databases'] : filename = "%s_%s.sql" % (db['name'], datetime.now().strftime("%Y%m%d-%H-%M-%S")) filepath = "%s/%s" % (conf['local-backup-path'], filename) cmd = "mysqldump -h%s -u%s -p%s -P%s --single-transaction %s > %s" % ( db['host'], db['user'], db['pass'], db['port'], db['name'], filepath ) os.system(cmd) cmd = "gzip %s" % filepath os.system(cmd) filepath = filepath + '.gz' dbx = dropbox.Dropbox(conf['dropbox-token']) backuppath = "%s/%s/%s/%s" % ( conf['remote-backup-path'], # remote path datetime.now().strftime("%Y%m%d"), # date string conf['server-name'], # server name filename + '.gz') with open(filepath, 'rb') as f: time = datetime.now().strftime("%Y-%m-%d %H:%M:%S ") print(time + "Uploading " + filepath + " to Dropbox as " + backuppath) try: dbx.files_upload(f.read(), backuppath, mode=WriteMode('overwrite')) except ApiErroras err: # This checks for the specific error where a user doesn't have # enough Dropbox space quota to upload this file if (err.error.is_path() and err.error.get_path().error.is_insufficient_space()): sys.exit("ERROR: Cannot back up; insufficient space.") elif err.user_message_text: print(err.user_message_text) sys.exit() else: print(err) sys.exit()
簡(jiǎn)單描述下這個(gè)代碼的思路,這個(gè)程序應(yīng)該滿(mǎn)足這個(gè)幾個(gè)要求:
- 使用 mysqldump 備份數(shù)據(jù)庫(kù)到本地
- 應(yīng)該支持配置文件,允許配置多個(gè)數(shù)據(jù)庫(kù)
- 可以上傳到 Dropbox
為了完成這些要求,首先碰到的難題是怎么支持配置文件,一搜,原來(lái) Python 下有個(gè)默認(rèn)的 ConfigParser,可以完成這個(gè)任務(wù),但是正常東西比較惡心的是,配置文件必須是以 [Section] 為單位組織的。其實(shí)我的配置顯然有些全局配置,還有就是數(shù)據(jù)庫(kù)的各種信息是多次重復(fù)的,這種配置文件,嵌套能力簡(jiǎn)直糟糕,必須兩層的結(jié)構(gòu),就很惡心。于是我去網(wǎng)上搜配置文件的格式,好多文章比較了各種配置文件的優(yōu)劣,其實(shí)這文章挺多的,我想了想,以后或許我也可以寫(xiě)文章講講我自己的感受了。反正就是很多文章最后都公認(rèn) YAML 是配置文件里最完美的。于是我也決定用這個(gè),果然也有現(xiàn)成的類(lèi)庫(kù),就是 PyYAML,特方便,就倆函數(shù) load 和 dump,直接就把文件變成 dict 格式了。
第二個(gè)難題,就是上傳 Dropbox,后來(lái)發(fā)現(xiàn),官方提供了很豐富的 API,而且直接就有 SDK,(讓我眼紅的是,官方竟然沒(méi)有 PHP 的 SDK,這么不受待見(jiàn)么?),研究 SDK 用法,發(fā)現(xiàn)直接就有代碼范例,于是直接抄到我的代碼里,瞬間完成了 50% 的代碼,爽!
整個(gè)代碼完成后,我發(fā)現(xiàn),寫(xiě)代碼一共也沒(méi)花多少時(shí)間,而且,我學(xué)會(huì)的 Python 的方式,我以前一直抱怨 Python 的文檔難用,我發(fā)現(xiàn),其實(shí),最好的方式其實(shí)是在交互式的 Shell 里,用 help 來(lái)查詢(xún) API,再輔佐以官方文檔,才是比較正確的方式。這是刷新了一個(gè)我以前的認(rèn)識(shí)的地方。實(shí)踐下來(lái)感覺(jué)還不錯(cuò)的。Python 的包管理器 pip 也很好用。
pip install PyYAML pip install dropbox
- Python讀寫(xiě)及備份oracle數(shù)據(jù)庫(kù)操作示例
- Python實(shí)現(xiàn)定時(shí)備份mysql數(shù)據(jù)庫(kù)并把備份數(shù)據(jù)庫(kù)郵件發(fā)送
- Python實(shí)現(xiàn)備份MySQL數(shù)據(jù)庫(kù)的方法示例
- python備份文件以及mysql數(shù)據(jù)庫(kù)的腳本代碼
- python使用多線(xiàn)程查詢(xún)數(shù)據(jù)庫(kù)的實(shí)現(xiàn)示例
- Python基于多線(xiàn)程操作數(shù)據(jù)庫(kù)相關(guān)問(wèn)題分析
- Python基于多線(xiàn)程實(shí)現(xiàn)抓取數(shù)據(jù)存入數(shù)據(jù)庫(kù)的方法
- python使用多線(xiàn)程備份數(shù)據(jù)庫(kù)的步驟
相關(guān)文章
解決python中的print函數(shù)自動(dòng)換行的問(wèn)題
這篇文章主要介紹了解決python中的print函數(shù)自動(dòng)換行的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02Python中斷點(diǎn)調(diào)試pdb包的用法詳解
pdb(python debugger) 是 python 中的一個(gè)命令行調(diào)試包,為 python 程序提供了一種交互的源代碼調(diào)試功能,下面就跟隨小編一起學(xué)習(xí)一下它的具體使用吧2024-01-01Python快速生成隨機(jī)密碼超簡(jiǎn)單實(shí)現(xiàn)
這篇文章主要介紹了Python快速生成隨機(jī)密碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08Python基于Gensim實(shí)現(xiàn)文本相似度/匹配/查重
Gensim是基于Python語(yǔ)言的自然語(yǔ)言處理庫(kù),用來(lái)主題建模、文本相似度等文本處理任務(wù),下面我們就來(lái)看看如何使用Gensim實(shí)現(xiàn)文本相似度/匹配/查重等操作吧2024-03-03python創(chuàng)建Flask Talisman應(yīng)用程序的步驟詳解
Flask是一個(gè)功能強(qiáng)大的Web框架,主要用于使用Python語(yǔ)言開(kāi)發(fā)有趣的Web應(yīng)用程序,Talisman基本上是一個(gè)Flask擴(kuò)展,用于添加HTTP安全標(biāo)頭我們的Flask應(yīng)用程序易于實(shí)施,本文就給大家講講帶Talisman的Flask安全性,需要的朋友可以參考下2023-09-09Linux環(huán)境下的Python打包和部署實(shí)踐
這篇文章主要介紹了Linux環(huán)境下的Python打包和部署實(shí)踐的相關(guān)資料,需要的朋友可以參考下2023-11-11淺談python出錯(cuò)時(shí)traceback的解讀
這篇文章主要介紹了淺談python出錯(cuò)時(shí)traceback的解讀,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07