sqlite3 のデータを MySQL へ移行する

sqlite3 は便利なのですが、MySQL を使いたい時があります。

dump ファイルを作成

sqlite3 のダンプファイルを作成します。


sqlite3 db.sqlite3 .dump > dump.sql

sqlite3-to-mysql.py の作成

Qiita のコードをそのまま頂きます。


import sys

def main():
    print("SET sql_mode='NO_BACKSLASH_ESCAPES';")
    lines = sys.stdin.read().splitlines()
    for line in lines:
        processLine(line)

def processLine(line):
    if (
        line.startswith("PRAGMA") or 
        line.startswith("BEGIN TRANSACTION;") or
        line.startswith("COMMIT;") or
        line.startswith("DELETE FROM sqlite_sequence;") or
        line.startswith("INSERT INTO \"sqlite_sequence\"")
       ):
        return
    line = line.replace("AUTOINCREMENT", "AUTO_INCREMENT")
    line = line.replace("DEFAULT 't'", "DEFAULT '1'")
    line = line.replace("DEFAULT 'f'", "DEFAULT '0'")
    line = line.replace(",'t'", ",'1'")
    line = line.replace(",'f'", ",'0'")
    in_string = False
    newLine = ''
    for c in line:
        if not in_string:
            if c == "'":
                in_string = True
            elif c == '"':
                newLine = newLine + '`'
                continue
        elif c == "'":
            in_string = False
        newLine = newLine + c
    print(newLine)

if __name__ == "__main__":
    main()

コンバート


cat dump.sql | python sqlite3-to-mysql.py > mysql.sql

インポート


mysql > source mysql.sql

簡単でいいのですが、猛烈に時間がかかります。

python ですべて自動的に

自分で作ってみました。
あまりかっこよくないですが、sqlite 3 のデータがすべて自動的に mysql に書き込まれます。

全部で 4 つのテーブルがあり、合計は 200 万行あるのですが、実行時間は約 30 秒です。


import pymysql
import sqlite3

class ToMysql:

    def __init__( self ):
        self.username = 'root'
        self.password = 'pass'
        self.mysqldb = 'stats_lapis'
        self.sql3 = '/home/user/stats_lapis.sql3'
        self.tblList = []
        self.manuDB('DROP DATABASE IF EXISTS stats_lapis')
        self.manuDB('CREATE DATABASE IF NOT EXISTS stats_lapis')

    def manuDB(self, sql):
        conn = pymysql.connect(host='localhost',
            user = self.username,
            password = self.password,
            charset='utf8')
        cur = conn.cursor()      
        cur.execute( sql )       
   
    def allTbl(self):
        conn = sqlite3.connect( self.sql3 )
        cur = conn.cursor()
        cur.execute('select * from sqlite_master where type="table"')
        tblinfos = cur.fetchall()
        for row in tblinfos:
            self.tblList.append(row[1])
        return tblinfos
        cur.close()
        conn.close()
      
    def createTbl(self, sqls):
        conn = pymysql.connect(host='localhost',
            db=self.mysqldb,
            user = self.username,
            password = self.password,
            charset='utf8')
        cur = conn.cursor()     
        for sql in sqls:
            esql = sql[4].replace('"','')
            cur.execute(esql)

    def writeData(self):
        for tbl in self.tblList:
            alldata = self.readData( tbl )
            self.insertData( tbl, alldata )
            
    def readData(self, tbl):
        conn = sqlite3.connect( self.sql3 )
        cur = conn.cursor()
        sql = 'SELECT * FROM ' + tbl
        cur.execute( sql )
        return cur.fetchall()
    
    def insertData(self, tbl, alldata ):       
        conn = pymysql.connect(host='localhost',
            db=self.mysqldb,
            user = self.username,
            password = self.password,
            cursorclass=pymysql.cursors.DictCursor)
        try:
            with conn.cursor() as cursor:
                sql = self.createSQL( tbl, alldata )
                cursor.executemany( sql, alldata )
            conn.commit()
        finally:
            conn.close() 
            
    def createSQL(self, tbl, alldata ):
        print(tbl)
        sn = []
        for cnt in range(len(alldata[0])):
            sn.append('%s')        
        sql = "INSERT INTO " + tbl + " VALUES ( " + ','.join(sn) + ")"
        return sql

if __name__ == "__main__":
    dcm = ToMysql()
    tblinfos = dcm.allTbl()
    dcm.createTbl( tblinfos )
    dcm.writeData()