[Python] 345 MySQL自動検索 全テーブル対象 結果CSV化

[M1 Mac, Big Sur 11.7.2, Python 3.10.4, MySQL 8.0.31]

MySQLで自動検索し、ヒットした行の全データをcsvファイルにまとめるスクリプトを書きました。

文字列にリストとしての機能を付与するeval関数を思い出すのに少々時間がかかりました。

久しぶりにリスト内包表記を使いました。相変わらずの優れものです。

import time,datetime,subprocess,os,csv,glob
import MySQLdb

# 今日の日付
today = datetime.date.today()
today_str = str(today)[2:].replace('-','')
print(today_str)

# MySQLの起動確認
proc = subprocess.run("mysqladmin ping", shell=True, stdout= subprocess.PIPE, stderr = subprocess.PIPE)
ping_result = proc.stdout.decode('UTF-8')
print(ping_result)

detect = "alive" in ping_result
if detect == False:
    os.system('mysql.server start')
else:
    print("MySQLは起動しています")

# MySQLに接続
conn = MySQLdb.connect(user='root')
cur = conn.cursor()

# 処理時間測定開始
start = time.time()

# データベースdataを選択
select_db = f"use data"
cur.execute(select_db)

# 全テーブルを取得
search_tables = f"show tables"
cur.execute(search_tables)
tables = cur.fetchall()
# print(f"tables : {tables}")

# 検索語と結果ファイル名の設定(同日同検索語の結果ファイルがあれば付番する)
key = 'suzuki'
csv_key = f"{today_str}_{key}"
csv_name = f"/code/Python/MySQL/csv/{today_str}_{key}.csv"
csvfiles = glob.glob(f'/code/Python/MySQL/csv/*.csv')

# リスト内包表記で同日同検索語の結果ファイル数をカウントする
csv_count = sum(csv_key in file for file in csvfiles)
if csv_count > 0:
    print(f'csv_count :{csv_count}')
    csv_num = csv_count + 1
    csv_name = f"/code/Python/MySQL/csv/{today_str}_{key}_{csv_num}.csv"

# 検索
hit = 0
num = 0
for table in tables:
    table2 = str(table).replace('(','').replace(')','').replace(",",'').replace("'",'`')
    print(f"table : {table2}")
    
    search = f"SELECT * FROM {table2} WHERE `Name` LIKE '%{key}%'"
    cur.execute(search)
    rows = cur.fetchall()

    for row in rows:
        print(row)
        row_str = str(row).replace('(','[').replace(')',']')
        print(row_str)
        with open(csv_name, 'a') as f:
            writer = csv.writer(f)
            writer.writerow(eval(row_str))
        hit = hit + 1
 
    # 処理時間算出(秒)
    process_time = time.time() - start
    td = datetime.timedelta(seconds = process_time).total_seconds()

    # 小数点第2位まで表示
    td_2f = f'{td:.2f}'
    print(td_2f)
    
    num = num + 1
    
    # テスト用(1テーブルのみ検索)
    # if num == 1:
    #     break
    
print(f'HIT数 :{hit}')

conn.close()
os.system('mysql.server stop')