概要
pythonを用いて
csvファイルの各行から値を読み取り
DBへinsertさせていきたい。
また、insertした後にテーブルのレコード状態を確認したいので
select結果もファイル出力させたい。
テーブル情報
テーブル名はpokevalueです。
mysql> desc pokevalue;
+-------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(1024) | YES | | NULL | |
| H | int(11) | YES | | NULL | |
| A | int(11) | YES | | NULL | |
| B | int(11) | YES | | NULL | |
| C | int(11) | YES | | NULL | |
| D | int(11) | YES | | NULL | |
| S | int(11) | YES | | NULL | |
| T | int(11) | YES | | NULL | |
+-------+---------------+------+-----+---------+-------+
input
以下の書式で、insertしたい値を記載した状態のcsvファイル
・対象テーブルのcolumnを先頭行に記載
・2行目以降はcolumn毎にinsertしたい値を記載
id,name,H,A,B,C,D,S,T
1,フシギダネ,45,49,49,65,65,45,318
2,フシギソウ,60,62,63,80,80,60,405
3,フシギバナ,80,82,83,100,100,80,525
output
・summary.log(select結果が吐かれる)
実装
sql_test.py(サブモジュール)
import pymysql
import pymysql.cursors
class MySQL:
conn = pymysql.connect(host=XXXX,
user=XXXX,
password=XXXX,
db=XXXX,
charset='utf8mb4'
)
# select
def query(stmt, *args):
try:
conn.ping()
with conn.cursor() as cursor:
cursor.execute(stmt, (args))
data = cursor.fetchall()
return data
finally:
conn.close()
cursor.close()
# insert
def ins_query(stmt, *args):
try:
conn.ping()
with conn.cursor() as cursor:
cursor.execute(stmt, (args))
data = cursor.fetchall()
finally:
conn.commit()
conn.close()
cursor.close()
return True
メインモジュールからquery()かins_query()を呼ばれます。
前者の場合はselect結果を返し
後者の場合はinsertするといった単純な作りです。
app.py(メインモジュール)
import csv
from sql_test import MySQL
csv_file = open("./pokevalue_insert.csv", "r", encoding="ms932", errors="", newline="")
f = csv.DictReader(csv_file)
for row in f:
ins_main = 'INSERT INTO pokevalue\
(id, name, H, A, B, C, D, S, T)\
VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s)'
MySQL.ins_query(ins_main, row["id"], row["name"], row["H"], row["A"], row["B"], row["C"], row["D"], row["S"], row["T"])
sel_main = 'SELECT * FROM pokevalue\
WHERE id=%s AND name=%s AND H=%s AND A=%s AND B=%s AND C=%s AND D=%s AND S=%s AND T=%s'
sel_value = MySQL.query(sel_main, row["id"], row["name"], row["H"], row["A"], row["B"], row["C"], row["D"], row["S"], row["T"])
with open('summary.log', mode='a') as log:
log.write("{0}{1}".format(str(sel_value), "\n"))
csvファイルはDictReader
によって辞書型で開き、キーを指定して変数に格納できる形にしました。
その為、csvファイルから読み取った行のカラムを指定して読み込むには
row[カラム名]
あるいはrow.get(カラム名)
のように指定してやります。
(もしかすると単にreader
で読み取って、forをネストしながらinsert文組み立てた方が良かった気もしますが今回はこれで。)
その後はins_mainにINSERT文を記述します。(VALUESの中身は可変なので変数%sとします)
そしてins_queryへの引数に、ins_mainとcsvファイルから読み取った値を渡してあげれば、無事テーブルにレコードがINSERTされます。(selectも同様の構造で書いています)
最後にselect結果をlogファイルに追記しています。
app.py実行結果
summary.log
((1, 'フシギダネ', 45, 49, 49, 65, 65, 45, 318),)
((2, 'フシギソウ', 60, 62, 63, 80, 80, 60, 405),)
((3, 'フシギバナ', 80, 82, 83, 100, 100, 80, 525),)
pokevalue
mysql> select * from pokevalue;
+------+------------------------------------------+------+------+------+------+------+------+------+
| id | name | H | A | B | C | D | S | T |
+------+------------------------------------------+------+------+------+------+------+------+------+
| 1 | フシギダネ | 45 | 49 | 49 | 65 | 65 | 45 | 318 |
| 2 | フシギソウ | 60 | 62 | 63 | 80 | 80 | 60 | 405 |
| 3 | フシギバナ | 80 | 82 | 83 | 100 | 100 | 80 | 525 |
参考記事
((1, 'フシギダネ', 45, 49, 49, 65, 65, 45, 318),)
((2, 'フシギソウ', 60, 62, 63, 80, 80, 60, 405),)
((3, 'フシギバナ', 80, 82, 83, 100, 100, 80, 525),)
mysql> select * from pokevalue;
+------+------------------------------------------+------+------+------+------+------+------+------+
| id | name | H | A | B | C | D | S | T |
+------+------------------------------------------+------+------+------+------+------+------+------+
| 1 | フシギダネ | 45 | 49 | 49 | 65 | 65 | 45 | 318 |
| 2 | フシギソウ | 60 | 62 | 63 | 80 | 80 | 60 | 405 |
| 3 | フシギバナ | 80 | 82 | 83 | 100 | 100 | 80 | 525 |