Python 및 CSV 파일에서 레코드 일괄 INSERT

개요

파이썬으로
csv 파일의 각 행에서 값을 읽습니다.
DB에 insert시켜 가고 싶다.
또한 삽입 후 테이블의 레코드 상태를 확인하고 싶기 때문에
select 결과도 파일 출력시키고 싶다.

테이블 정보

테이블 이름은 pokevalue입니다.

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    |       |
+-------+---------------+------+-----+---------+-------+

입력

이하의 형식으로, insert 하고 싶은 값을 기재한 상태의 csv 파일

・대상 테이블의 column을 선두행에 기재
・2행째 이후는 column마다 insert하고 싶은 값을 기재

pokevalue_insert.csv
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 (서브 모듈)

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 (주 모듈)

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 |

참고 기사

파이썬에서 CSV 파일로드

좋은 웹페이지 즐겨찾기