Home > Tags > sqlite

sqlite

SQLite で複数のスキーマを扱う

SQLite をあるプロダクトのテストに使ってます。テストを自動化する時のセットアップコストがそんなにかからなくてすごく良いです。普通のファイルと同じような感覚で使えるのは Good。

SQLite をテスト用途に使っていると、たまに「外部キー制約サポートされてないんだよなぁー」と思うことはありますが、それでもトランザクションに対応しているとか、まぁ主要な機能はきちんとおさえてくれてるので好きです。

で、本題。

SQLite って同一コネクションで (スキーマ分割して) 複数のデータベースを扱うことってできるのかな?

テスト関係で SQLite を使ってるときに、スキーマ分割されたデータベースを作ることができると嬉しいなという状況に遭遇しました。そこで SQLite のドキュメント の SQL Syntax のページをざーっと眺めてみてそれっぽいものを探してみたところ、ATTACH DATABASE というコマンドがありました。これを使えば複数のデータベースを attach して、一つのコネクション上に複数のスキーマを混在させるといった使い方ができそうです。そこで、ドキュメント読んで試してみました。

まずは、普通に hoge.db というデータベースに items というテーブルを作ります。

% sqlite3 hoge.db
SQLite version 3.4.2
Enter ".help" for instructions
sqlite> create table items (
   ...>   id integer not null primary key,
   ...>   name text
   ...> );
sqlite> .q

items テーブルを作ったらひとまず SQLite Shell を出ます。

次に、 fuga.db というデータベースに、 hoge.db と同じ items テーブルを作ります。fuga.db の items テーブルにはデータを一行だけ入れておきます(後で確認するため)。

% sqlite3 fuga.db
SQLite version 3.4.2
Enter ".help" for instructions
sqlite> create table items (
   ...>   id integer not null primary key,
   ...>   name text
   ...> );
sqlite> insert into items (name) values ('in fuga');
sqlite> select * from items;
1|in fuga
sqlite> .q

これで hoge.db, fuga.db にそれぞれ items テーブルが存在することになります。これらを一度に扱いたいとしましょう。

SQLite には .databases というコマンドを SQLite Shell の中で使えるようなのでこれを試してみます。まずは、 hoge.db に接続します。

% sqlite3 hoge.db
SQLite version 3.4.2
Enter ".help" for instructions
sqlite> .databases
seq  name             file
---  ---------------  ----------------------------------------------------------
0    main             /home/keiji/workspace/sqlite3/hoge.db

なんかそれっぽい表示が出てきました。しめしめという感じで、ここで ATTACH DATABASE を使って fuga.db を attach させてみます。

ドキュメント上の Syntax を確認すると

sql-statement ::= ATTACH [DATABASE] database-filename AS database-name

とあるので、

sqlite> attach 'fuga.db' as fuga;
sqlite>

どうやら上手く attach できたみたいなので、再び .databases コマンドで確認してみます。

sqlite> .databases
seq  name             file
---  ---------------  ----------------------------------------------------------
0    main             /home/keiji/workspace/sqlite3/hoge.db
2    fuga             /home/keiji/workspace/sqlite3/fuga.db

なんか fuga という データベース名(スキーマ名) で、現在のコネクションに fuga.db が attach されたようです。SQL を叩いて確認してみます。

sqlite> select count(*) from items;
0
sqlite> select count(*) from fuga.items;
1
sqlite> select * from fuga.items;
1|in fuga
sqlite>

上手くいったみたいです。やたー!スキーマ分割されてるケースのテストも SQLite 使えるー。ここまで分かれば当たり前だけど、言語側からも問題なく使えた。

因みに、テーブル名がデータベース間で重複していなければ、データベース名で修飾する必要はないみたいです。

sqlite> create table fuga.people (
   ...>   name text
   ...> );
sqlite> insert into fuga.people (name) values ('kjim');
sqlite> insert into people (name) values ('kjim');
sqlite> select * from fuga.people;
kjim
kjim
sqlite> select * from people;
kjim
kjim

PostgreSQL で言う SET とか、あればなおいいんだけどなぁ。見落としてるかもしれないけど、どうやらなさそうなのでそこは残念。

まぁでもやっぱり組み込みデータベースとして使える SQLite っていい。

Java から使うときは h2database を薦めるけどね。

Home > Tags > sqlite

Search
Feeds
Meta

Return to page top