sqlite3 - python DBファイルで:memory:を初期化する
sqlite3.connect(':memory:') でインメモリのDBを使う場合に中身を初期化しておきたい場合があります。一つの方法としてSQLを実行する方法があります。
conn = sqlite3.connect(':memory:', isolation_level=None) c = conn.cursor() sqls = [ 'CREATE TABLE table1 (data1 INTEGER, data2 INTEGER);', 'INSERT INTO "table1" VALUES(1, 2);', 'INSERT INTO "table1" VALUES(3, 4);' ] for sql in sqls: c.execute(sql)
この方法でも良いのですが、データの量が多いと時間がかかります。たとえばカラム数4千でレコード数3万の場合2分ほど。これらの全てのカラムにインデックスを張った場合2時間ほどかかりました。
これでは時間がかかりすぎます。そこでSQLを実行するのではなく、事前に作成しておいたDBファイルをそのまま読み込んで初期化する方法を紹介します。
まずapswモジュールが必要になるので、こちらから落としてインストールしておきます。
そして、DBファイルで初期化を行う手順は以下のようになります。
import sqlite3 import apsw _conn = apsw.Connection(':memory:') #1 conn = sqlite3.connect(_conn) #2 src_conn = apsw.Connection('src.db') #3 with _conn.backup("main", src_conn, "main") as backup: while not backup.done: backup.step(100) #4
- :memory: で apsw のコネクションを作成
- apsw で sqlite3 のコネクションを作成
- 初期化用のDBファイルで apsw のコネクションを作成
- 初期化用BDから :memory: へデータをコピーしていく
backup.step(100) で指定している数値は一度にコピーするページサイズです。小さくすればwhileが多く回りますが、適当な数値を入れておけば何を指定して問題ないと思います。
この方法を使うと、SQL文を実行したときにかかってた2時間が、なんと10秒まで短縮されました。