銀月の符号

Python 使い見習いの日記・雑記

SQLAlchemy で Firebird その0

まる 1 日かかって Python, SQLAlchemy 経由で Firebird データベースが扱えるようになったけれど、なにを行ってきたのか忘れそうなので覚書を残す。記録をとっておかないと名前に惹かれてつかってみようと思い至ったもののあっさり挫折した 3 年前の自分にすぐ戻りそうだ。

今回は環境の準備について。タイトルに反して SQLAlchemy はまだでてこない。

環境

とりあえず Firebird 用意しないと始まらない

firebird2.1-super (version 2.1.3.18185-0.ds1-6build1(lucid)) パッケージがあるので入れるだけ。 configure; make; make install; よりも簡単ってどうなのよ?

ちなみに Python からアクセスするための kinterbasdb も python-kinterbasdb (version 3.3.0-2) という名でパッケージが用意されている。ついでに SQLAlchemy もあるけれど python-sqlalchemy(version 0.5.8-1) とバージョン 0.5.8 だったのでこちらは easy_install sqlalchemy で 0.6.3 にした。

パッケージから入れ終わったら、 SYSDBA のパスワードの設定。

$ sudo dpkg-reconfigure firebird2.1-super

適当に変更しておく(最大8文字)。以下、記事内でのパスワードは masterkey としておく。

その後は firebird のユーザーを作成する。

$ gsec -user SYSDBA -password masterkey

gsec のインタラクティブモードに入る。ここでは display で既存ユーザーの確認、 add 'spam' -pw 'spamspam' で パスワード spamspam のユーザー spam の作成、 delete 'spam' で ユーザー spam の削除となる。

最後にデータベースファイルの置き場所の用意。どこでもいいけれど Firebird 専用とするため既存のディレクトリは使わず mkdir する。できたらアクセス権限の設定。 sudo chgrp firebird .; sudo chmod 770 . して、 firebird グループがアクセスできるようにすれば OK 。

起動と停止

まずは Firebird の起動、停止、再起動を覚えねば…。

$ sudo /etc/init.d/firebird2.1-super start
$ sudo /etc/init.d/firebird2.1-super stop
$ sudo /etc/init.d/firebird2.1-super restart

isql-fb で初めての Firebird

次にデータベースの作成。 Firebird だと 1 データベースは 1 ファイルとなる。
データベースを作るときはファイルパスを指定することになる(エイリアスをつけておけばこれでも可能、後述)。
カレントディレクトリに spam.fdb というデータベースファイルを作るには次のようにする。

$ isql-fb -u spam -p spamspam
Use CONNECT or CREATE DATABASE to specify a database
SQL> CREATE DATABASE 'spam.fdb' DEFAULT CHARACTER SET UTF8;
SQL> COMMIT;

特別な意図がなければデータベースのデフォルト文字コードの指定をしておくと吉。今回はふつうに UTF8 で。

データベースができたので、早速接続してみる。

SQL> CONNECT 'spam.fdb';
Database:  'spam.fdb', User: spam

なにかテーブル作ってみる

SQL> CREATE TABLE abc(
CON>   a INTEGER PRIMARY KEY,
CON>   b INTEGER,
CON>   c INTEGER NOT NULL
CON> );

なにか INSERT してみる。

SQL> INSERT INTO abc(a, b, c) VALUES (1, 10, 100);
SQL> INSERT INTO abc VALUES (2, 20, 200);
SQL> INSERT INTO abc(a, c) VALUES (3, 300);
SQL> COMMIT;

カラムの指定をしなかった場合は全部の列を定義順に指定したものとして扱われる。カラムの値を指定していないものがある場合 DEFAULT の値が入る。 DEFAULT がなければ null が入る。NOT NULL 制約が入っているカラムの値を省略した場合、 null を入れようとするができないのでエラーとなる、とまぁイメージどおりの挙動。

とりあえず SELECT してみる。

SQL> SELECT * FROM abc;

           A            B            C 
============ ============ ============ 
           1           10          100 
           2           20          200 
           3       <null>          300 

うん、データベース作ってテーブル作って値入れることができることを確認。

Python, kinterbasdb で初めての Firebird

kinterbasdb は DB-API 2.0 準拠。 connect するさいは dsn にファイルパス(or エイリアス)、 user にユーザー名、 password にパスワードを指定するようにする。

$ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import kinterbasdb
>>> conn = kinterbasdb.connect(dsn='spam.fdb', user='spam', password='spamspam')
>>> cur = conn.cursor()
>>> cur.execute('SELECT * FROM abc')
>>> for row in cur:
...   print row
... 
(1, 10, 100)
(2, 20, 200)
(3, None, 300)

問題なく。

でもデータベースにアクセスするのにファイルパスでってどうなのよ?

ファイルの場所が明らかになってしまっていたり、(Firebird がアクセスできる場所に)データベース作り放題だったり。そんな疑問をもったらエイリアスとアクセス制限を行う。 aliases.conf と firebird.conf の DetabaseAccess で設定できる。これらの設定ファイルは /etc/firebird/2.1 ディレクトリにある。

エイリアスを設定すればファイルパスを直接扱わなくてもよくなる。

DatabaseAccess に None を指定すればファイルパスでのアクセスを禁止できる。 Restrict を指定すればファイルパス指定でアクセスできるディレクトリを限定できる。

インストール直後の aliases.conf, firebird.conf には設定例が満載されているので一目見ればなんとなくわかるようにできている。

aliases.conf
# ------------------------------
# List of known database aliases
# ------------------------------

#
# Example Database:
#
employee.fdb = /var/lib/firebird/2.1/data/employee.fdb
employee = /var/lib/firebird/2.1/data/employee.fdb

#
# Live Databases:
#
firebird.conf(一部抜粋)
# ----------------------------
# Database Paths/Directories
#
# DatabaseAccess may be None, Full or Restrict. If you choose Restrict,
# provide ';'-separated trees list, where database files are stored.
# Relative paths are treated relative to RootDirectory entry
# (see above). Default value 'Full' gives full access to all files
# on your site. To specify access to specific trees, enum all required
# paths (for Win32 this may be something like 'C:\DataBase;D:\Mirror',
# for unix - '/db;/mnt/mirrordb'). If you choose 'None', then only
# databases listed in aliases.conf can be attached.
#
# Note: simple quotation marks shown above should *NOT* be used when
# specifying values and directory path names. Examples:
#
# DatabaseAccess = None
# DatabaseAccess = Restrict C:\DataBase
# DatabaseAccess = Restrict C:\DataBase;D:\Mirror
# DatabaseAccess = Restrict /db
# DatabaseAccess = Restrict /db;/mnt/mirrordb
# DatabaseAccess = Full
#
# UNCONTROLLED DATABASE ACCESS MAY COMPROMISE YOUR SYSTEM!
# IT IS STRONGLY RECOMMENDED THAT THIS SETTING BE USED TO LIMIT
# DATABASE LOCATIONS!
#
# Type: string (special format)
#
#DatabaseAccess = Full


# ----------------------------

これで準備 OK 。次は SQLAlchemy を、といったところで時間切れ。続く…。

おまけ Windows からも Python, kinterbasdb でアクセス

Firebird 2.1.3 のインストーラーを公式サイトより持ってきてインストール。途中でインストール内容を聞かれるけれども、クライアントだけで OK 。そして Python, kinterbasdb を用意したら準備完了。

リモートのデータベースにアクセスするには dsn に ipアドレス or ホスト名:パス名 or エイリアス と指定するようにする。

Python 2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import kinterbasdb
>>> conn = kinterbasdb.connect(dsn='192.168.xxx.xxx:spam', user='spam', password=
'spamspam')

接続できたらあとは同じ。

おまけ VirtualBox のホストからゲストへのアクセス

VirtualBox のホストからゲストへアクセスできるようにするには設定、ネットワークアダプタからホストオンリーアダプタを追加する。