python3でテキストファイルからデータベース(sqlite3)に取り込む
はじめに
今回はテキストファイルをsqlite3に取り込む方法を紹介します。
DBはsqlite3を使用しました。
ちょっとした、データ分析のために使用する予定なので、
単一ファイルで管理が楽なsqlite3を選択しました。
今回は例として歌詞のテキストデータをデータベースに取り込みたいと思います。
準備
まずは取り込むテキストのサンプルを作ります。
下記を「test.txt」として保存します。
In my nikke 歌手 BUMP OF CHICKEN 作詞 Motoo Fujiwara 作曲 Motoo Fujiwara 俺とヒロは夢の中 ヒロは俺の友達さ それをバンプが邪魔をした ヒロと俺は離れ離れ ヒロのハートに突き刺され(突き刺され)
次に取り込むデータを入れるためのDBを作成します。
DBアクセスツールとしてDB Browser for SQLiteを使用するため、
ダウンロードしてインストールします。
起動して、New Databaseでデータベースを作成します。
今回dbの名前は「music」とします。
作成したら、テーブルを作成する画面が表示されます。
サンプルテキストの情報を取り込みたいので、
今回は以下のようなテーブルを作りました。
CREATE TABLE `artist_song_lyrics` ( `seq` INTEGER NOT NULL, `artist` TEXT NOT NULL, `song` TEXT NOT NULL, `sakushi` TEXT, `sakkyoku` TEXT, `lyrics` TEXT NOT NULL, PRIMARY KEY(`seq`) )
カラムは以下の内容です。
seq:シークエンス(連番) artist:アーティスト名 song:曲名 sakushi:作詞家 sakkyoku:作曲家 lyrics:歌詞
本当は正規化をした方がいいのですが、今回はめんどくさいのでやりません。
正規化しない方がSQLは簡単にかけるし、速度追わないなら正規化いらないですね。
プログラム
ファイル取り込みプログラム「main.py」。
今回拡張性を考えて、データベースを触る処理はDatabaseOpeとしてクラス化した。
歌詞データは同じフォーマットで来ることを想定して、
行数を見て、各種データを取り出している。(なんか、バカっぽいやり方だなぁ)
ファイルオープンモジュールは文字コードエラーが怖いのでcodecsを使った。
seqは曲を複数取り込むことを想定して、DBを見てから付番するようにしている。
# -*- coding: utf-8 -*- #ライブラリインポート import DatabaseOpe import io import os import sys import codecs import linecache #設定値 dbName = "music.db" textName = "test.txt" #デフォルトエンコードをutf-8にする。 sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') #データベース読み込み DBpath = os.path.normpath(os.path.join(os.path.abspath(__name__),'../')) + '/' + dbName DB = DatabaseOpe.DatabaseOpe(DBpath) #ファイル読み込み f = codecs.open(textName, 'r', 'utf-8') lines2 = f.readlines() # 1行毎にファイル終端まで全て読む(改行文字も含まれる) f.close() #変数宣言 lyrics = "" #行ごとに読み取り for i,line in enumerate(lines2): # print(i) if i == 0: song = line.replace('\n','') elif i == 2: artist = line.replace('\n','') elif i == 3: sakushi = line.replace('\n','') elif i == 4: sakkyoku = line.replace('\n','') elif i > 5: lyrics = lyrics + line.replace('\n','').replace('\r','') + '\n' #文字整形 lyrics = lyrics[:-2] artist = artist[3:] sakushi = sakushi[3:] sakkyoku = sakkyoku[3:] #DBインサート DB.insertArtist(DB.getArtistSeq(),artist,song,sakushi,sakkyoku,lyrics)
データベース操作クラス「DatabaseOpe.py」。
今回はここにSQLをベタ書きした。
個人的にはsqlは専用のテーブルを作って、DB内で管理した方が管理しやすいと思う。
# -*- coding: utf-8 -*- import sqlite3 import datetime class DatabaseOpe: def __init__(self,DBpath): self.con = sqlite3.connect(DBpath, isolation_level=None) self.cur = self.con.cursor() # ファイルテーブルseq取得処理 def getArtistSeq(self): self.cur.execute("select max(seq) from artist_song_lyrics;") seq = self.getSeqInc(self.cur.fetchall()[0]) return seq # インサート処理 def insertArtist(self,seq,artist,song,sakushi,sakkyoku,lyrics): self.cur.execute("insert into artist_song_lyrics (seq,artist,song,sakushi,sakkyoku,lyrics) values (?,?,?,?,?,?);",(seq,artist,song,sakushi,sakkyoku,lyrics))
おわり
今回は機械学習や統計処理をするときに、よく使うであろうファイル操作とDB操作を行った。
ちょっとした、データ分析とかでデータの取り扱いをするならsqliteが便利です。