PythonスクリプトによるデータベースのDropboxへの自動バックアップ

4582 ワード

最近、ちょうど1件の大事が発生して、GitLabの運維の学友はうっかり生産のデータを削除して、GitLabはすでに驚くべき5種類のバックアップのメカニズムを用意しましたが、しかし依然として彼らが6時間近くのユーザーのデータを失って、特に彼らの名声の損失に対して、まったく計り知れないことです.反省してみると、このブログBecomin'Charlesも、完璧なバックアップがなくて、本当に冷や汗が出ていますね.主にこれが私の個人ブログだと考えていますが、もう10年近く堅持していると思います.もし本当になくしたら、とても心が痛いです.
ちょうど、妻は最近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 " % 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()

このコードの考え方を簡単に説明します.このプログラムはこのいくつかの要求を満たすべきです.
  • mysqldumpを使用してデータベースをローカル
  • にバックアップ
  • は、複数のデータベース
  • の構成を可能にするプロファイルをサポートする必要があります.
  • はDropbox
  • にアップロードできます
    これらの要件を満たすために、まず直面する難題はどのようにプロファイルをサポートするかであり、検索すると、Pythonの下にデフォルトのConfigParserがあり、このタスクを完了することができますが、通常のものが気持ち悪いのは、プロファイルが[Section]単位で組織されている必要があります.実は私の配置は明らかにいくつかのグローバルな配置があって、それからデータベースの各種の情報は何度も繰り返して、このような配置ファイル、ネストの能力はまったく悪くて、2層の構造が必要で、とても気持ち悪いです.そこで私はネット上で配置ファイルのフォーマットを探して、多くの文章は各種の配置ファイルの優劣を比較して、実はこの文章はとても多くて、私は考えて、後で私も文章を書いて自分の気持ちを話すことができるかもしれません.いずれにしても、多くの文章が最後にYAMLがプロファイルの中で最も完璧だと公認しています.そこで私もこれを使うことにしました.やはり既成のクラスライブラリもあります.PyYAMLです.とても便利で、2つの関数loadとdumpだけで、直接ファイルをdict形式にしました.
    2つ目の難題は、Dropboxをアップロードすることです.その後、公式は豊富なAPIを提供しており、直接SDKがあることに気づきました.SDKの使い方を研究して、直接コードの例があることを発見して、そこで直接私のコードの中で写して、瞬間的に50%のコードを完成して、さわやかです!
    全体のコードが完成した後、私はコードを書くのに全部であまり時間がかからないことを発見しました.そして、私が学んだPythonの方法は、私は以前ずっとPythonのドキュメントが使いにくいと文句を言っていました.私は発見しました.実は、最も良い方法は実はインタラクティブなシェルの中で、helpでAPIを調べて、公式のドキュメントを補佐するのが正しい方法です.これは私の以前の認識を更新した場所です.実践してみるといい感じです.Pythonのパッケージマネージャpipも使いやすいです.
    
    pip install PyYAML
    pip install dropbox