2021年5月2日日曜日

Pythonでmysqldumpを実行する

 MySQLやMariaDBのテーブルバックアップをPythonで実行してみたので、その方法をまとめておく。


環境


WSL2(Ubuntu20.04)。


MySQLの設定


通常mysqldumpコマンドを実行するときにはパスワードなどの入力が求められる。Pythonで実行するにはこの入力を省略できるようにする。これはMySQLの自動バックアップを設定するのようにホームディレクトリにパスワードなどを入力した「.my.cnf」を配置することで可能になる。

.my.cnfの中身は次のようにユーザー名とパスワードを記載しておく。

[mysqldump]
user=mysqluser
password=password

最後にパーミッションを設定しておく。


Pythonでmysqldumpを実行する

Pythonでmysqldumpを実行するためにsubprocessモジュール(Pythonのsubprocessでコマンドを実行する)を使う。

以下のコードでは、mydbデータベースのmytableテーブルをダンプしてgzip圧縮する。MySQLではオプション--skip-column-statisticsが必要。

import os
import io
import subprocess
from pathlib import Path

def dump_table(dbhost, dbname, tblname, mariadb=True):
    dump_path = tblname+'.sql.gz'
    if mariadb:
        com_dump = 'mysqldump --defaults-file=~/.my.cnf -h {} {} {}'.format(dbhost, dbname, tblname)
    else:
        # --skip-column-statistics
        # MySQLではこのオプションがないと "Unknown table 'COLUMN_STATISTICS' in information_schema (1109)" が発生する
        com_dump = 'mysqldump --defaults-file=~/.my.cnf --skip-column-statistics -h {} {} {}'.format(dbhost, dbname, tblname)

    ps1 = subprocess.Popen(com_dump.split(' '), stdout=subprocess.PIPE)
    with open(dump_path, 'wb') as f:
        ps2 = subprocess.Popen(['gzip'], stdin=ps1.stdout, stdout=f)
        ps1.stdout.close()
    
    # プロセス終了まで待つ
    outs, errs = ps2.communicate()

    # ダンプしたファイルの確認
    p = Path(dump_path)
    if p.is_file():
        dump_size = os.path.getsize(dump_path)
        print('dump_path=', dump_path)
        print('dump_size=', dump_size)
    else:
        raise Exception('Failed to dump: [dbname={}] [tblname={}]'.format(dbname, tblname))

def main():
    # データベースのホスト
    dbhost = 'localhost'

    # データベース名
    dbname = 'mydb'

    # ダンプするテーブル
    tblname = 'mytable'

    dump_table(dbhost, dbname, tblname)

if __name__ == '__main__':
    main()

このコードを実行するとzip圧縮されたダンプファイルがmytable.sql.gzとして作成される。

0 件のコメント:

コメントを投稿