SQLite 関連


  2006/10/05 更新

SQLite とは?

http://www.sqlite.org/


  クライアント サーバー型の RDBMSでなく、データベースファイルの内容をSQL 言語で操作できるライブラリになっているものです。
 イメージ的には MS-Access の、SQL エンジンだけを取り出したような感じで、Firebird/Interbase を使ったことがある方なら、Firebird のサーバーとクライアントのライブラリを一つにまとめて、Stored Procedure や generator の機能を削除しさらに、Role の機能をなくした感じです。

  バージョンが 2.x のものと 3.x の2系統あって、両者はデータの内部形式から、ライブラリ名、コマンド名も異なるものです。両者を同時にインストールすることもできるようです。

通常、2.x 系のコマンドラインツールが sqlite 、3.x 系のツールが sqlite3 になります。

以前のバージョンから新しい SQLite3 の形式のデータに変更するには、下のようにする。

$ sqlite OLD.DB .dump | sqlite3 NEW.DB

普通は、 SQLite 3.x  を使えば良いと思います。 以下は、SQLite3 をベースに説明しますが、使い方については SQLite 2.x でもほとんど同じです。

1.インストール

 わたしは、http://www.sqlite.org/ からダウンロードして configure & make しました。

 ここで、configure で GNU make 用の Makefileが作成されるので、GNU make が標準でない環境では、あらかじめインストールしておきます。

 私は FreeBSD 上で ports から gmake をインストールした後で、以下のようにしました。

$ ./configure
$ gmake
# gmake install

 附属の testcase が tcl で書かれているので、tcl バインディングもコンパイルしたかったのですが、configure で、どういうパラメータを渡せば良いかわからなくて、早々に挫折しました。
tcl バインディングをコンパイルしなくても、普通に使うことはできます。
Linux や Windows の人は、RPM や、バイナリがあるのでそれを使えば良いでしょう。

2.使い方

$ sqlite3 foo

とすると、foo という名前のファイル = データーベースが作成されて、コマンドラインから SQL文が実行できる状態になります。既に、foo というデータベースが作成されていれば、fooというデータベースを開いてそのデータベースへの操作ができるようになります。

$ sqlite3 foo <bar.sql

とすると、bar.sql に書かれた SQL文が実行されます。

3.Python モジュール

 pysqlite モジュールも、1.x 系と、2.x 系が存在し 2.x 系は 1.x のバージョンアップというよりは、再実装したものです。両者を同時にインストールすることも可能なようです。どちらの系統のものも、最新のものは、 SQLite3 のライブラリとリンクするようになっています。

 http://initd.org/tracker/pysqlite から、辿ったダウンロードページで、最新 をダウンロードして、

$ python setup.py install

でインストールできました。
ダウンロードしたファイルの test フォルダーに testcase が入っていますので、使い方は、そちらを参考にしてみて下さい。

インストールされた /usr/bin/test-pysqlite の実行で、いつでもテストでいます。

4.Zope Database Adapter

  ZGadflyDA をベースに、SQLite の DAを作りました

0.2以前は pysqlite モジュールが、0.3 以降は、pysqlite2 モジュールが必要です。

5.ざっと使ってみた感想

 SQL 標準じゃないけど、Oracle の SEQUENCE 表に相当する機能が欲しいです。
テーブルの作成時に INTEGER PRIMARY KEY として、そのカラムには値を INSERT しなければ良いようです。

 実装されていない SQL の機能 http://www.sqlite.org/omitted.html の中で、CHECK制約や、外部キー制約が使えないのもちょっと残念です。

 型がない http://www.sqlite.org/datatypes.html ということなので、例えば「この列は、timestampだぜ!」と宣言しても、結局、文字列でもなんでも入れることができてしまいます。
 トランザクション の機能はあるので、制約については、アプリケーション(プログラム)でちゃんと矛盾のないようにしておいてね、ということなのでしょう。(そういうところで楽したいから RDBMS使うんですが・・・)

 しかし、いろいろ、細かい点で文句はあっても、インストールが簡単(ファイルがコピーされて、パスが通っていれば良い)という他にないメリットもあるので、適用場面をちゃんと判断できれば良いと思います。

 あとは、速度ですが、本当のところはどうなんでしょう。これは、データ量にもよるし、インデックスを付けるかどうか、にもよるんでしょうが(http://snap.shot.cx/ZWiki/SQLite)実際のところ、どうなのかは、誰かのレポートを希望します。

 さらにいうと、日本語がちゃんと使えるかどうかも誰か試してみてください。UTF-8 だと、ある程度、ちゃんと使えるっぽいです( http://www.sqlite.org/version3.html )。

 それから、Python から pysqlite 経由で SQLite を使ってみると、数値型の値でも、文字列型として fetch するようなので、ちょっと困ります。(前述の型がないっていうのと関係あると思うのですが・・・)

cur.execute('select count(*) from foo')
cur.fetchone()

とすると、pysqlite だと

>>> ('1',)

となります。
ちなみに、psycopgだと

>>> (1L,)

なんですが・・・

間違えてました (2003/07/03)

上の例でいえば、
cur.execute('select count(*) from foo')
cur.execute('-- types int')
cur.fetchone()

としてやれば、数値として取ってこれるようです。(ZenKai の 2003/07/02の日記参照)

-- types int, float, str

という感じに、fetch する前に、型を指定してあげれば良いらしいです。

 も読んでおいたほうが良いでしょう←自分)


6.pysqlite2 で日本語を使う場合の注意点

 sqlite3(コマンドラインツール) や pysqlite2 を使って、EUC-JP 等のコードで文字列を INSERT することはできます(入力された文字コードのまま格納されるようです)。同様に、sqlite3 で、そのデータベースからその文字列を、あるがままに SELECT することはできます。

 しかし、pysqlite2 で fetch する時には、格納されている文字列を UTF-8 だとみなして、UTF-8→UNICODE 変換をしているようです。そのため、EUC-JP や ShiftJIS で保存された SQLite3 のDBから pysqlite2 では fetch できないようです。

 よって、pysqlite2 を使って、SQLite3 を操作する場合は、データを UTF-8 で格納する必要があるようです。pysqlite2 で、cur.execute() に渡す文字列を、UTF-8 か、UNICODE にすれば良いようです。

その他情報


Zope メモ