首頁  >  文章  >  後端開發  >  Python腳本實作會自動將資料庫備份到 Dropbox

Python腳本實作會自動將資料庫備份到 Dropbox

高洛峰
高洛峰原創
2017-02-09 17:57:551934瀏覽

最近,正好發生了一件大事,就是GitLab 的運維同學不小心刪除了生產的數據,雖然GitLab 已經駭人聽聞的準備了五種備份機制,但是,仍然導致他們丟失了將近6 個小時的用戶數據,尤其對他們聲譽的損失,是根本無法估量的。反思一下,這個博客Becomin' Charles,也是沒有完善的備份的,真是冷汗直冒啊,主要考慮到這是我的個人博客,但是想想已經堅持了快十年了,如果真的丟了的話,還是非常痛心的。

正好,老婆最近正在學習Python 編程,我在教她,其實,我是PHP 程序員,一點也不喜歡Python,但是說實在,一個外行學編程的話,Python 確實比PHP 友好太多了,只能推薦她學Python 了。剛好,藉著這個機會,我決定自己也學 Python 程式設計吧,於是,我決定要用 Python 做一個資料庫的自動備份腳本。備份的位置,就用Dropbox 來做吧,因為我的伺服器是 Linode 提供的,美國 fremont 機房,選擇美國的儲存服務,比較適合。以下是我寫得程式碼,Python 小白,請指教:

#!/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], &#39;r&#39;))
  
# 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[&#39;databases&#39;] :
  filename = "%s_%s.sql" % (db[&#39;name&#39;], datetime.now().strftime("%Y%m%d-%H-%M-%S")) 
  filepath = "%s/%s" % (conf[&#39;local-backup-path&#39;], filename)
  cmd = "mysqldump -h%s -u%s -p%s -P%s --single-transaction %s > %s" % (
      db[&#39;host&#39;],
      db[&#39;user&#39;], 
      db[&#39;pass&#39;], 
      db[&#39;port&#39;], 
      db[&#39;name&#39;], 
      filepath
      )
  os.system(cmd)
  cmd = "gzip %s" % filepath
  os.system(cmd)
  filepath = filepath + &#39;.gz&#39;
  dbx = dropbox.Dropbox(conf[&#39;dropbox-token&#39;])
  backuppath = "%s/%s/%s/%s" % (
      conf[&#39;remote-backup-path&#39;],    # remote path
      datetime.now().strftime("%Y%m%d"), # date string
      conf[&#39;server-name&#39;],       # server name
      filename + &#39;.gz&#39;)
  with open(filepath, &#39;rb&#39;) 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(&#39;overwrite&#39;))
    except ApiErroras err:
      # This checks for the specific error where a user doesn&#39;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()

簡單描述下這個程式碼的思路,這個程式應該滿足這個幾個要求:

使用mysqldump 備份資料庫到本地

應該支援設定文件,使用mysqldump 備份資料庫到本地

應該支援設定文件,允許配置多個資料庫

可以上傳到Dropbox

為了完成這些要求,首先碰到的難題是怎麼支持配置文件,一搜,原來Python 下有個默認的ConfigParser,可以完成這個任務,但是正常東西比較噁心的是,設定檔必須是以[Section] 為單位組織的。其實我的配置顯然有些全域配置,還有就是資料庫的各種資訊是多次重複的,這種配置文件,嵌套能力簡直糟糕,必須兩層的結構,就很噁心。於是我上網搜尋設定檔的格式,好多文章比較了各種設定檔的優劣,其實這文章挺多的,我想了想,以後或許我也可以寫文章講講我自己的感受了。反正就是很多文章最後都公認 YAML 是設定檔裡最完美的。於是我也決定用這個,果然也有現成的類別庫,就是 PyYAML,特方便,就倆函數 load 和 dump,直接就把文件變成 dict 格式了。

第二個難題,就是上傳Dropbox,後來發現,官方提供了很豐富的API,而且直接就有SDK,(讓我眼紅的是,官方竟然沒有PHP 的SDK,這麼不受待見麼?) ,研究SDK 用法,發現直接就有程式碼範例,於是直接抄到我的程式碼裡,瞬間完成了50% 的程式碼,爽!

整個程式碼完成後,我發現,寫程式碼一共也沒花多少時間,而且,我學會的Python 的方式,我以前一直抱怨Python 的文檔難用,我發現,其實,最好的方式其實是在互動的Shell 裡,用help 查詢API,再輔佐以官方文檔,才是比較正確的方式。這是刷新了一個我以前的認識的地方。實踐下來感覺還不錯的。 Python 的套件管理器 pip 也很好用。

pip install PyYAML
pip install dropbox
🎜更多Python腳本實現自動將資料庫備份到 Dropbox相關文章請關注PHP中文網! 🎜
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn