파이썬에서 CSV, TSV 파일을 SQLite로 가져 오는 방법

소개





파이썬에서 SQLite DB로 CSV 및 TSV 데이터를 가져오고 싶습니다!
그런 분들을 위한, 스크립트 일발로 임포트 하는 방법의 해설입니다.

SQLite란 무엇인가, 어떻게 셋업하는지 등은 이하의 기사를 참고해 주세요.
Python과 SQLite로 실현되는 로컬로 간편한 SQL 환경 작성술

가져오기 방법



사용법은 이 아래의 "해설"에서.

스크립트



import_data_to_sqlite.py
import sqlite3
import csv
import os

#######↓ここのパラメータを変える↓#######
dbname = ''
target_table_name = ''
import_table_name = ''
is_create_table = 
is_header_skip = 
#####################################


#######↓インポート先のテーブルDDL↓#######
sql_script = """

"""
#######################################

class ImportSQLite():
    def __init__(self, dbname, target_table_name, import_data_name, is_create_table, is_header_skip=False, sql_create_table=None):
        """
        csvまたはtsvファイルをSQLiteへインポートする
        :param dbname: text 接続先DB名
        :param target_table_name: text インポート先となるDB上のテーブル名
        :param import_data_name: text インポートしたいデータ名
        :param is_create_table: boolean インポート先となるテーブルを作成するか否か
        :param is_header_skip: boolean インポートするデータのヘッダーを読み飛ばすか否か
        :param sql_create_table: text インポート先となるテーブルのDDL
        """
        self.dbname = dbname
        self.target_table_name = target_table_name
        self.import_data_name = import_data_name
        self.is_create_table = is_create_table
        self.is_header_skip = is_header_skip
        _, raw_delimiter = os.path.splitext(import_data_name)
        if raw_delimiter == '.csv':
            self.delimiter = ','
        elif raw_delimiter == '.tsv':
            self.delimiter = '\t'
        else:
            raise ValueError('Import file should be csv or tsv.')

        if is_create_table:
            if not sql_create_table:
                raise ValueError('It\'s necessary of sql to create table')
            else:
                self.sql_create_table = sql_create_table


    def read_import_file(self):
        with open(self.import_data_name, 'r', encoding='utf-8') as f:
            reader = csv.reader(f, delimiter=self.delimiter)
            if self.is_header_skip:
                header = next(reader)

            return [i for i in reader]


    def pick_column_num(self, import_data):
        """
        インポートファイルの列数を算出する
        :param import_data: array(two-dimensional)
        :return: int
        """
        columns = []
        for raw in import_data:
            columns.append(len(raw))
        if len(set(columns)) == 1:
            return columns[0]
        else:
            raise ValueError('this import files has diffrenect column numbers.')


    def insert_csv_file(self):
        input_file = self.read_import_file()
        column = self.pick_column_num(input_file)
        val_questions = ['?' for i in range(column)]
        cur.executemany("insert into {0} values ({1})".format(self.target_table_name, ','.join(val_questions)), input_file)


if __name__ == '__main__':

    sql = ImportSQLite(
        dbname=dbname,
        target_table_name=target_table_name,
        import_data_name=import_table_name,
        is_create_table=is_create_table,
        is_header_skip= is_header_skip,
        sql_create_table=sql_script
    )

    conn = sqlite3.connect(sql.dbname)
    cur = conn.cursor()

    if sql.is_create_table:
        cur.execute('drop table if exists {};'.format(target_table_name))
        cur.execute(sql.sql_create_table)

    sql.insert_csv_file()

    conn.commit()
    conn.close()


해설



설정 항목




변수 이름
금형
설정 방법


dbname
텍스트
연결할 DB 이름. 경로의 형태로 지정한다.

target_table_name
텍스트
가져올 DB의 테이블 이름

import_table_name
텍스트
가져올 데이터의 이름. 경로의 형태로 지정한다.

is_create_table
Boolean(True or False)
가져올 대상 테이블을 만들지 여부

is_header_skip
Boolean(True or False)
가져올 데이터의 헤더를 읽을지 여부


여러 주의


  • 가져올 테이블을 만들 때 생성 쿼리를 설정하지 않으면 오류가 발생합니다.
  • csv,tsv 이외의 파일을 인풋으로서 지정하면 연주됩니다.

  • 사용법 및 샘플



    예를 들면 다음과 같은 CSV가 있고, 접속처의 DB에는 아직 테이블이 없었던 경우

    students.csv
    id,name,class,blood_type
    1,Mike,Moon,B
    2,Bob,Song,A
    3,Gonzalez,Star,AB
    4,Alex,Moon,
    

    설정 항목은 다음과 같습니다.

    (서두) import_data_to_sqlite.py
    #######↓ここのパラメータを変える↓#######
    dbname = 'test.db' # '/home/user/test.db'といった形で指定も可能
    target_table_name = 'students'
    import_table_name = 'students.csv' # '/home/user/students.csv'といった形で指定可能
    is_create_table = True
    is_header_skip = True
    #################################
    
    
    #######↓インポート先のテーブルDDL作成↓#######
    sql_script = """
    create table students(
        id integer,
        name text,
        class text,
        blood_type text
    );
    """
    #######################################
    

    나머지는 정상적으로 시작할 뿐

    kick.sh
    $ python import_data_to_sqlite.py
    

    끝.

    좋은 웹페이지 즐겨찾기