1.3. クラス

DALを使うには構成するクラスを知る必要があります。これらのクラスについて説明します。

1.3.1. 主要なクラス

DALには非常に多くのクラスが含まれます。この中にはフレームワークを利用する上で、どうしても知っている必要があるクラスがあります。このようなクラスを次に挙げてみます。

クラス 説明 詳細説明
DAL データベースに関するクラス DAL
Field フィールドに関するクラス Field
Table テーブルに関するクラス Table
Query 条件式に関するクラス Query
Expression 式に関するクラス Expression
Set レコードセット定義に関するクラス Set
Rows レコードセットに関するクラス Rows
Row レコードに関するクラス Row

これらのクラスとその主な機能(メソッド)を表したのが次の図になります。

DALクラス — データベースに関するクラス

コンストラクタ

データベース接続

define_table()

テーブル定義

commit()rollback()

トランザクション制御

executesql()

直接SQL文を実行

export_to_csv_file()

全テーブルのCSVエクスポート

import_from_csv_file()

複数テーブルのCSVインポート

tables()

テーブル一覧

smart_query()

スマートクエリ

Fieldクラス — フィールドに関するクラス

コンストラクタ

フィールド定義

count()

フィールドのカウント

formatter()

フィールドのバリデータ表示フォーマット値

validate()

フィールドのバリデータ

Tableクラス — テーブルに関するクラス

insert()

レコードの追加

bulk_insert()

レコードをまとめて追加

update_or_insert()

レコード更新or追加

validate_and_insert()

バリデータとレコード追加

truncate()

全レコードの削除

drop()

テーブルの削除

import_from_csv_file()

CSVファイルからのインポート

with_alias()

テーブル別名設定

fields()

テーブルのフィールド一覧

_insert()

SQL文生成

_drop()

SQL文生成

_truncate()

SQL文生成

_enable_record_versioning()

レコードバージョン管理

— ショットカット機能(リスト型エミュレーション) —

myrecord = db.mytable[id]レコードの取得
db.mytable[0] = dict(myfield='value')レコードの追加
db.mytable[id] =dict(myfield='value')レコードの更新
del db.mytable[id]レコードの削除

— ショットカット機能(関数エミュレーション) —

row = db.mytable(id)レコードの取得(ID指定)
row = db.mytable(db.mytable.id==id)レコードの取得(Query指定)
row = db.mytable(myfield='value')レコードの取得(パラメータ指定)
row = db.mytable(id,myfield='value')レコードの取得(id,辞書型)

Queryクラス — 条件式に関するクラス

case()

SQLのCASE式による置換

as_dict()

クエリ式を辞書値に変換

as_json()

クエリ式をjsonに変換

as_xml()

クエリ式をxmlに変換

Expressionクラス — 式に関するクラス

— 条件式 —

like()

あいまい検索

startswith()

前方一致検索

endswith()

後方一致検索

contains()

部分一致検索

belongs()

IN演算子

regexp()

正規表現による検索

— データ操作 —

sum()

合計値計算

avg()

平均値計算

max()

最大値の取得

min()

最小値の取得

len()

長さの取得

abs()

絶対値取得

coalesce()

NULL値の変換

coalesce_zero()

NULL値のゼロ変換

upper()

大文字変換

lower()

小文字変換

year()

日付時間の要素抜き出し

month()

day()

hour()

minutes()

seconds()

Setクラス — レコードセット定義に関するクラス

select()

レコードセット取得

count()

レコード件数取得

isempty()

レコード存在チェック

update()

レコードの更新

update_naive()

レコードの更新
(コールバック関数の無視)

validate_and_update()

バリデータとレコード更新

delete()

レコードの削除

nested_select()

ネストしたSELECT

_select()

SQL文生成

_count()

SQL文生成

_update()

SQL文生成

_delete()

SQL文生成

Rowsクラス — レコードセットに関するクラス

first()

最初のレコードを取得

last()

最後のレコードを取得

as_dict()

辞書型に変換

as_list()

リスト型に変換

as_trees()

木構造のデータをリスト型に変換

find()

レコードセット内検索

exclude()

レコードセットの切り抜き

sort()

レコードセットのソート

setvirtualfields()

仮想フィールドの設定

export_to_csv_file()

CSVファイルへのエクスポート

xml()

xml/htmlに変換

json()

jsonに変換

Rowクラス — レコードに関するクラス

as_dict()

辞書型に変換

— 組み込み関数 —

update_record()

Rowと共にDB上のレコードも更新

delete_record()

Rowと共にDB上のレコードも削除

クラスとそのクラスに属する機能(メソッド)を知るのは、DALを使いこなす上で重要な事項になります。

1.3.2. DAL構文とクラスの関係

次にDAL構文とクラスの関係について、サンプルコードを使って示してみます。

データベース接続

サンプルコード

>>> db = DAL('sqlite://storage.db')

サンプルとクラスの関連図

../../_images/web2py_dal_002r.JPG

テーブル定義

サンプルコード

>>> db.define_table('person',
...     Field('name'), format='%(name)s')

サンプルとクラスの関連図

../../_images/web2py_dal_003r.JPG

レコード検索と出力

サンプルコード

>>> rows = db(db.person.id > 0).select()
>>> for row in rows:
...     print row.name
...
Potamata
Cotasata
Tamodama

サンプルとクラスの関連図

../../_images/web2py_dal_004r.JPG

クラスをコード断片毎に、詳細に見ていきます。

コード クラス
db DAL
db.person Table
db.person.id Field
db.person.id > 0 Query
db() DAL
db(db.person.id > 0) Set
rows = db(db.person.id > 0).select() Rows
row = rows[0] Row
row.name 文字列

DAL構文とクラスは密接に関係しているということが、理解できるのではないでしょうか。

1.3.3. DALとTable、Fieldクラスについて

DALはデータ接続、Tableはテーブル、Fieldはフィールドに関するクラスですが、これらは交互に互いのクラスにアクセス可能になっています。
DALクラスの属性としてTableクラスが、Tableクラスの属性としてFieldクラスへのアクセスができます。
コード クラス
db DAL
db.person Table
db.person.id Field

DALとTableクラスの基底クラスは、dict(辞書)クラスです。このため次のように辞書型として各クラスにアクセス可能です、

コード クラス
db DAL
db[‘person’] Table
db.person.[‘id’] Field
db[‘person’][‘id’] Field

親となる接続やテーブルに、クラスを逆に遡ることも可能です。

Fieldクラス
コード クラス
db.person.id Field
db.person.id._table Table
db.person.id._db DAL

Tableクラス
コード クラス
db.person Table
db.person._db DAL
これらは属性として管理されています。
また次のように、接続やテーブルの名前を文字列として参照可能な属性もあります。
コード 文字列
db.person.id._tablename ‘person’
db.person._tablename ‘person’
db.person._db ‘sqlite’
db._uri ‘sqlite://storage.sqlite’

また、DALクラスやTableクラスのオブジェクトはイテレータとして、TableオブジェクトやFieldオブジェクトを取り出すことが可能です。

>>> for t in db:
...     print t
...
auth_user
auth_group
auth_membership
auth_permission
auth_event
auth_cas
person
>>> for f in db.person:
...     print f
...
person.id
person.name

詳細は、 DAL , Table , Field を参照ください。

1.3.4. QueryとExpression クラスについて

QueryとExpressionと2つのクラスがありますが、Queryは条件式、Expressionは式に関するクラスです。
具体的に示してみます。

Queryクラス

>>> qry = db.person.name == 'Potamata'  # personのnameが'Potamata'とイコールという条件式
>>> type(qry)
<class 'gluon.dal.Query'>

qryはQueryインスタンスになります。

Expressionクラス

>>> exp = db.item.unit_cost * 1.1       # コスト単価を1.1倍にする式
>>> type(exp)
<class 'gluon.dal.Expression'>

expはExpressionインスタンスです。

これらのインスタンスは、他のクラスのメソッドなどの引数として使用することになります。

またExpressionクラスは、Queryクラスを返すメソッドを幾つか持っています。

サンプルコード

>>> qry = db.person.name.like('P%')
>>> type(qry)
<class 'gluon.dal.Query'>

db.person.nameはFieldクラスですが、FieldクラスはExpressionクラスを継承しています。このためExpressionクラスのメッソド like の呼び出しが可能です。likeメソッドは、あいまい検索のQueryインスタンスを返します。

詳細は、 Query , Expression を参照ください。

1.3.5. Set Rows Row クラスについて

Set Rows Row の各クラスは具体的に、どんなクラスなのでしょうか。この3つのクラスを説明したのが次の図です。

../../_images/web2py_dal_005r.PNG

Set Rows Row 関係図

Setはレコードセットを定義していますが、データの実体としては何もありません。Rowsインスタンスが生成された時点で、初めてクエリを実行します。そして、データベースからデータが取り出されてメモリ上に格納します。

Rowsはメモリ上にあるレコードの塊と考えればよいです。

RowはRowsをさらに分解して、一レコード単位にしたものです。

RowsとRowのインスタンスは、既にデータベースから切り離されています。このためRows及びRowインスタンスのデータを改変しても、データベース上のデータには影響しません。

Rowsはイテレータを使用し、Rowを取り出すことができます。

サンプルコード

>>> rows = db(db.person.id > 0).select()
>>> for row in rows:
...     print row.name
...
Potamata
Cotasata
Tamodama

また基底クラスが、dict(辞書)クラスではありませんが、RowsやRowは辞書型をエミュレートします。

Rowsクラス
コード クラス
rows = db(db.person.id > 0).select() Rows
row = rows[0] Row
rows[0][‘name’] 文字列

Rowクラス
コード クラス
row.name 文字列
row[‘name’] 文字列
row(person.name) 文字列

詳細は、 Set , Rows , Row を参照ください。