3.1. DAL¶
DALクラスのインスタンス生成よって、データベースへの接続が可能になります。この他に、テーブル定義・ トランザクション制御・テーブルデータのエクスポート・インポート・SQL文の実行などの機能をメソッドで提供しています。
参考: Dependencies | 依存関係
DALクラス — データベースに関するクラス | |
---|---|
データベース接続 | |
テーブル定義 | |
トランザクション制御 | |
直接SQL文を実行 | |
全テーブルのCSVエクスポート | |
複数テーブルのCSVインポート | |
テーブル一覧 | |
スマートクエリ |
3.1.1. インスタンス化¶
DALインスタンスの生成は、DALクラスのコンストラクタを使用します。またDALインスタンス名は、デフォルトでは db で設定されています [1] 。
【 DALインスタンスの生成とアクセス 】
- 生成・・・・・・ コンストラクタ を使用します。
- アクセス・・・デフォルトのインスタンス名は db です。
-
class
dal.
DAL
→ DALインスタンス¶ コンストラクタはデータベースへの接続処理をします。
>>> db = DAL('sqlite://storage.db')
Parameters: - uri – 接続文字列
- pool_size – 接続プール
- db_codec – データベースのエンコード文字列
- check_reserved – 予約語チェック
- migrate – マイグレーション
- fake_migrate – テーブル定義の再構築
- migrate_enabled – マイグレーションが可能かどうかの設定
- fake_migrate_all – 全テーブルで定義の再構築
- attempts – 接続失敗時の再試行数
- bigint_id –
big-id
,big-reference
の使用 - lazy_tables – テーブル定義の遅延実行
- do_connect – データベースへの接続をするかどうか
Returns: DALインスタンス
- uri
接続文字列については 接続文字列 を参照ください。デフォルト値は ‘sqlite://dummy.db’ です。
- 複数のデータベースへの接続試行
接続文字列にリスト形式で複数の接続先を記述すると、コンストラクタは順番に接続を試みます。 これは負荷分散目的でデータベースの複製がある場合に利用可能です。
>>> db = DAL(['接続文字列1', '接続文字列2', '接続文字列3', ])
接続文字列1、接続文字列2、接続文字列3 と順番に接続を試していきます。
- pool_size
データベース接続でのコネクション数を設定します。デフォルト値は0です。0場合は接続プールは使用しません。
GAE及びSQLiteではこの設定は無視されます。
参考: Connection Pooling | 接続プール
- db_codec
- データベースのエンコディングの設定です。デフォルトはUTF-8です。
- check_reserved
データベースの予約語が使われているか、チェックを行うかどうかの設定です。デフォルト値はNoneです。
詳細は参考サイトを参照ください。
参考: Reserved Keywords | 予約されたキーワード
- migrate
マイグレーションの設定をします。マイグレーションとはモデル(テーブル)定義が変更になった場合、 自動でデータベース上のテーブルも変更する動作のことです。
デフォルト値はTrueです。モデル定義が変更になった場合に、データベース上のテーブルも変更します。
データが格納されたテーブルのマイグレーションをどうするかなど、考慮すべき点はたくさんあります。詳細は参考サイトを参照ください。
参考: Migrations | マイグレーション
- migrate_enabled
接続時に全てのマイグレーションを有効・無効に指定できます。
デフォルトは True です。 False を指定した場合、全てのマイグレーションが無効になります。 複数のアプリケーションがデータベースを共有する場合、一つを除いてマイグレーションを無効にすることが推奨されているので、そのような状況下で使用します。
- fake_migrate
マイグレーションの失敗で、モデル定義とデータベーステーブルが不整合になったのを再構築します。
dal.DAL.define_table()
メソッドのパラメータとの違いは、define_table はテーブル単位ですが、こちらは全テーブルのマイグレーション問題の 修復をを試みます。しかしこのパラメータの機能では、失敗した場合の原因の究明は難しいです。デフォルト値はFalseです。再構築する場合はTrueにし、migrateをFalseにします。 再構築完了したらFalseに戻します。詳細は参考サイトを参照ください。
- attempts
接続失敗時の再試行数の設定です。デフォルトは5です。
参考: Connection Failures | 接続の失敗
- bigint_id
id
及びreference
フィールドタイプをそれぞれbig-id
とbig-reference
にする場合、Trueで指定します。 デフォルトは False です。- lazy_tables
- テーブル定義
define_table()
の実行を遅延させます。 モデルで定義したテーブル中で不使用のものがある場合に、このパラメータを指定すると実行速度が上がります。 デフォルトはFalseです。 - do_connect
データベースの接続を実際にするかどうかを設定します。デフォルト値はTrueです。 もしFalseを指定した場合、データベースには接続されません。 その場合はアプリケーションは動作しますが、例えば、次のメソッドを使用することはできません。
select()
、insert()
、update()
、delete()
SQL文を生成するだけの次のメソッドは使用可能です。
3.1.2. メソッド¶
-
DAL.
define_table
(tablename, *fields[, **args]) → Tableインスタンス¶ テーブルの定義をします。
db.define_table('person', Field('name'), format='%(name)s')
- tablename
- テーブル名を文字列で設定します。
- *fields
- フィールド定義は複数の設定が可能です。定義ではFieldクラスを使用します。
定義方法は
Field
を参照ください。 - **args
オプションを指定します。複数のオプションを指定可能です。設定可能なオプションは次の通りです。
- format
レコードの表示方法を指定します。 formatオプションの動作は formatオプションの動作 で説明します。
設定は、「文字列フォーマット操作」形式もしくは無名関数(lambda)で指定します。
- 文字列フォーマット操作
format='%(name)s'
- 変数はRowインスタンスになります。つまり内部では次のように変換されます。
'%(name)s' % Rowインスタンス
- 無名関数
format=lambda x: x.name or 'anonymous'
参考: Record Representation | レコードの表現
- migrate
マイグレーションログを保存するファイルの名を指定します(省略可能)。 指定したファイル名はアプリケーションの database フォルダに生成されるファイル名になります。
デフォルトは True です。Trueだとweb2pyの接続文字列のハッシュ値からファイル名を生成します。 False を指定した場合、定義したテーブルのマイグレーションは行われません。
この他、詳細は参考サイトを参照ください。
参考: Migrations | マイグレーション
- fake_migrate
マイグレーションの失敗で、モデル定義とデータベーステーブルが不整合になったのを再構築します。
デフォルト値はFalseです。再構築する場合はTrueにし、migrateをFalseにします。 再構築完了したらFalseに戻します。詳細は参考サイトを参照ください。
- primarykey
レガシテーブルの利用時に、複数フィールドでキーを設定する場合に使用します。 設定するフィールドをリスト形式で指定します。
primarykey=['ivtype','ivno']
指定しなくてもリストで指定したフィールドは、NOT NULL をセットします。
primarykey は今のところ、DB2、MS-SQL、Ingres、Informix のみ指定できます。
primarykeyの設定では レガシデータベースの利用 も参照ください。
- common_filter
コモンフィルタ を設定します。
この他、次のオプションも設定可能です。
singular , plural , trigger_name , sequence_name , polymodel , table_class
- 戻り値
- 戻り値はTableインスタンスが返ってきます。しかしこれは定義した時点で db.tablenameに関連付けられるため、捉える必要性はありません。
テーブル設定に関しては レガシデータベースの利用 と テーブルの継承 も参照ください。
-
DAL.
commit
()¶ トランザクション制御のコミット処理を行います。
>>> db.commit()
web2py のモデル・ビュー・コントロール のコードは、web2pyによって制御コードが付加されます。 このため、より細かな制御を望まない限り、コミット・ロールバックを記述する必要はありません。
-
DAL.
rollback
()¶ トランザクション制御のロールバック処理を行います。
>>> db.rollback()
web2py のモデル・ビュー・コントロール のコードは、web2pyによって制御コードが付加されます。 このため、より細かな制御を望まない限り、コミット・ロールバックを記述する必要はありません。
-
DAL.
executesql
(query[, placeholders, as_dict, fields, colnames]) → 実行結果¶ SQL文を実行できます。
>>> print db.executesql('select * from person') [(1, u'Syble Zee'), (2, u'Nathanial Azzano'), (3, u'Loreen Depierre')] >>> print db.executesql('select * from numbers;') [(1, 8, 71, 799), (2, 954, 364, 402)]
DALではインデックス作成は複雑になるのでサポートしていません。必要なインデックスはこのコマンドを使用して作成可能です。
>>> db.executesql('CREATE INDEX IF NOT EXISTS myidx ON person (name);') []
- query
- SQL文を設定します。
- placeholders
プレースホルダ(Queryの置き換え)変数を指定できます。 プレースホルダの構文はDALでは解析されないため、データベースエンジン・ドライバに依存します。
>>> print db.executesql('select * from person where id=:test', placeholders={'test':1}) [(1, u'Syble Zee')]
- as_dict
SQL文の実行結果を出力方法を変更できます。デフォルトはFalseです。Trueにした場合、辞書型で結果を出力します。
>>> print db.executesql('select * from person', as_dict=True) [{'id': 1, 'name': u'Syble Zee'}, {'id': 2, 'name': u'Nathanial Azzano'}, {'id': 3, 'name': u'Loreen Depierre'}] >>> print db.executesql('select * from numbers',as_dict=True) [{'a': 8, 'c': 799, 'b': 71, 'id': 1}, {'a': 954, 'c': 402, 'b': 364, 'id': 2}]
- fields
SQL文の実行結果とフィールドをマッチングするために指定します。 指定は Field オブジェクトをリストで指定します。 もし Table オブジェクトで指定した場合、 テーブルに含まれる全てのフィールドを指定したことと同等になります。 このパラメータを指定すると結果は、通常のDALクエリと同様に Rows オブジェクトで返ってきます。
fieldsを指定しない場合
>>> rows= db.executesql('select * from person,dog where person.id==dog.owner_id') >>> print rows [(1, u'Syble Zee', 1, 1, u'Guadalupe Dadlani'), (2, u'Nathanial Azzano', 2, 2, u'Sook Liechti'), (3, u'Loreen Depierre', 3, 3, u'Hong Burnet'), (3, u'Loreen Depierre', 4, 3, u'Melonie Osterloh')]
Fieldオブジェクトで指定した場合
>>> rows= db.executesql('select * from person,dog where person.id==dog.owner_id', ... fields=[db.person.id, db.person.name, db.dog.id, db.dog.owner_id, db.dog.name]) >>> print rows person.id,person.name,dog.id,dog.owner_id,dog.name 1,Syble Zee,1,1,Guadalupe Dadlani 2,Nathanial Azzano,2,2,Sook Liechti 3,Loreen Depierre,3,3,Hong Burnet 3,Loreen Depierre,4,3,Melonie Osterloh
Tableオブジェクトで指定した場合
>>> rows= db.executesql('select * from person,dog where person.id==dog.owner_id', ... fields=[db.person, db.dog])
- colnames
fieldsパラメータの代わりに、
テーブル名.フィールド名
の形式で、実行結果とフィールドをマッチングさせます。>>> rows= db.executesql('select * from person,dog where person.id==dog.owner_id', ... colnames=['person.id', 'person.name', 'dog.id', 'dog.owner_id', 'dog.name'])
colnames は fields と同時に指定することも可能です。この場合、colnamesの指定値はフィールドのラベルになります。
>>> rows= db.executesql('select * from person,dog where person.id==dog.owner_id', ... fields=[db.person, db.dog], ... colnames=['person id', 'name', 'dog id', 'dog owner', 'dog name']) >>> for row in rows: ... print row['name'] +' - '+ row['dog name'] ... Syble Zee - Guadalupe Dadlani Nathanial Azzano - Sook Liechti Loreen Depierre - Hong Burnet Loreen Depierre - Melonie Osterloh
なお web2py Book には fieldsとcolnamesを同時に指定する場合、fieldsには Expression オブジェクトを 追加可能という記述がありますが、少なくともSQLiteでは動作しないようです。
- 戻り値
- SQL文の実行結果を返します。
-
DAL.
export_to_csv_file
()¶ アプリケーションの全てのテーブルを、CSV形式でエクスポートします。
Rowsクラスの export_to_csv_file メソッドを内部でコールしています。 パラメータも同一です。詳細は
export_to_csv_file()
を参照ください。
-
DAL.
import_from_csv_file
()¶ CSVファイルから、アプリケーションの複数テーブルのインポートを行います。。
Tableクラスの import_from_csv_file メソッドを内部でコールしています。 パラメータも同一です。詳細は
import_from_csv_file()
を参照ください。
-
DAL.
tables
() → リスト値¶ 定義されているデータベース一覧を返します。
>>> db.tables ['auth_user', 'auth_group', 'auth_membership', 'auth_permission', 'auth_event', 'auth_cas', 'numbers', 'person', 'dog', 'feed', 'cat', 'inventory', 'mouse']
- 戻り値
- テーブル一覧のリスト値
3.1.3. 特殊メソッド¶
DALクラスには、いくつか特殊なメソッドが存在します。今回ここでは DALインスタンスに対してテーブル名を辞書型で指定すると、 Table インスタンスを返す特殊メソッドを紹介します。構文は次のようになります。
DALインスタンス[テーブル名] → Tableインスタンス
このメッソドを利用した例としては、アクセス制御で利用する Auth テーブルを考えることができます。Authテーブルはカスタマイズが可能で、 テーブル名自体も変更できます。例えば、auth_user テーブルの名前を変更する場合は、auth.settings.table_user_name 属性値に 新しい名前を設定します。このテーブルの Tableインスタンスを取得したい場合、次のように直接名前を指定することも可能ですが、 ハードコーディングになってしまいます。
>>> rows = db(db.auth_user).select() >>> for row in rows: ... print row.first_name, row.last_name ... Datatodu Tacemapo Dumacesa Datomoce
次のように特殊メソッドを使った方法で指定すれば、名前を変更した場合にプログラムソースを変更する必要がなくなります。
>>> rows = db(db[auth.settings.table_user_name]).select() >>> for row in rows: ... print row.first_name, row.last_name ... Datatodu Tacemapo Dumacesa Datomoce
3.1.4. 属性¶
-
DAL.
_dbname
¶ データベース名を保持する属性です。
>>> print db._dbname sqlite
-
DAL.
_lastsql
¶ 最後に実行したSQL文を保持する属性です。これは
executesql()
メソッドを使った場合も使わない場合も、全て記録されます。>>> rows = db().select(db.numbers.ALL) >>> print db._lastsql SELECT numbers.id, numbers.a, numbers.b, numbers.c FROM numbers;
-
DAL.
_timings
¶ データベースドライバーに渡された、SQL文と実行時間(秒)をタプルで保持しています。
>>> db._timings [('SELECT person.id, person.name, person.birthday FROM person WHERE (person.id> 0);', 0.004999876022338867), ("INSERT INTO person(name) VALUES ('test');", 0.003000020980834961)]
-
DAL.
_uri
¶ 接続文字列を保持する属性です。
>>> print db._uri sqlite://storage.sqlite
[1] | Pythonのinstance型オブジェクトではありませんが、簡単に説明するために インスタンス という言葉を使用しています。 |