3.3. Table

Tableはデータベーステーブルに関するクラスです。メソッドはレコード挿入・テーブル削除などの、レコード・テーブル操作機能を持っています。

レコードの検索・更新・削除の機能は、 Set が受け持っています。ただ Tableクラスも特殊 メソッドの機能によって限定的ですが、レコード検索・更新・削除機能を利用できます。

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,辞書型)

3.3.1. インスタンス化

Tableインスタンスの生成は、 define_table() メソッドを使用します。このメソッドはテーブル定義を行います [1]

また既に定義されているテーブルの場合は、 db.テーブル名 でTableインスタンスにアクセスできます。

【 Tableインスタンスの生成とアクセス 】

  • 生成・・・・・・ コンストラクタ を使用します。

  • アクセス・・・定義されているテーブルへは db.テーブル名 です。

    >>> table = db.person           # personテーブルの Tableインスタンス
    

3.3.2. メソッド

メソッド説明用サンプルでは次のテーブルを利用します。

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

db.define_table('dog',
    Field('owner_id', db.person),
    Field('name'))
Table.insert(**fields) → レコードid

レコードの挿入を行います。戻り値は挿入したレコードのid番号になります。

>>> db.person.insert(name="Pocomaco")
3
>>> db.dog.insert(name='Todamopa', owner_id='3')
1
**fields
キーワードパラメータで、フィールド名とその値を指定します。テーブルに含まれるフィールドを指定可能です。 idフィールドは指定できません。
戻り値
挿入したレコードのid番号です。

参考: insert挿入

Table.bulk_insert(*records) → リスト型レコードid

複数のレコードをまとめて挿入します。戻り値は挿入したレコード番号になります。

>>> db.person.bulk_insert([{'name':'Pocomaco'}, {'name':'Satocoto'}, {'name':'Codatada'}])
[3, 4, 5]
>>> db.dog.bulk_insert([{'owner_id':1,'name':'Todamopa'}, {'owner_id':2,'name':'Daceduce'}])
[1, 2]
*records
辞書型でレコード単位にフィールド名とその値を指定します。 辞書型で指定したレコードをリスト型で囲み複数のレコードを指定します。
戻り値
挿入したレコードのid番号をリスト型で返します。

通常のデータベースではinsertメソッドの使用と比べて、この機能の利用は特にメリットがありません。 しかし Google App Engine(GAE)では、大幅な高速化が期待できます。

参考: insert挿入

Table.update_or_insert([_key=DEFAULT, **values]) → None もしくは レコードid

レコードが存在する場合は更新を、存在しない場合はレコード挿入を行います。

>>> db.dog.update_or_insert(name='Cesocepo')            # name='Cesocepo'は存在するので更新

>>> db.dog.update_or_insert(name='test')                # name='test'は存在しないので挿入
4

>>> db.dog.update_or_insert(db.dog.name=='Comoceta', name='Comoceta', owner_id=2)       # キー(式)を指定

>>> db.dog.update_or_insert(name='Comoceta', owner_id=1)        # nameとowner_idの値が同じレコードが存在しないので挿入
5
_key
キーとして式を指定できます。辞書型でない第一パラメータをキーとして認識します。 キーはレコード検索時の条件になります。
**values
更新・挿入するレコードのフィールドと値を、キーワードパラメータで指定します。
戻り値
更新の場合は None を、挿入の場合は レコードid を戻します。

このメソッドのレコード検索は、 関数へのエミュレーション を利用しています。

Table.validate_and_insert([**fields]) → Rowオブジェクト

レコード挿入時、バリデータを行います。バリデータはフォームやSQLフォームで実施されるため、通常ではこのメソッドは使用しません。

>>> db.person.validate_and_insert(name='a'*513) # バリデータエラー
<Row {'errors': <Row {'name': 'enter from 0 to 512 characters'}>, 'id': None}>

>>> db.person.validate_and_insert(name='a'*512) # レコード挿入成功
<Row {'errors': <Row {}>, 'id': 4}>

>>> db.person.insert(name='a'*513)      # insertメソッドではバリデータを実施しないので挿入される
1

nameフィールドはstring型のため、デフォルトでは512文字より大きい場合バリデータで制限されます。

**fields
挿入するレコードのフィールドと値を、キーワードパラメータで指定します。
戻り値
Rowオブジェクトを返します。エラーがある場合は ‘errors’ の辞書値に、フィールド名がキーでエラーメッセージが値の辞書型データが設定されます。 挿入成功時は、’id’ の辞書値にレコードのidが設定されます。

よく似た機能で、 validate_and_update() も存在します。

Table.truncate([mode=None])

全レコードを削除して、id番号をリセットします。

>>> db.person.truncate()
mode

SQLの TRUNCATE TABLE文を渡す時にオプションを指定することが可能です。 このオプションはSQL文のため、データベース固有になります。

>>> db.person.truncate('RESTART IDENTITY CASCADE')

SQLite固有のオプションで、idカウンタのリセットを指定します。

参考: insert挿入

Table.drop()

テーブルの削除を行います。

>>> db.person.drop()

参考: dropドロップ

Table.import_from_csv_file(csvfile[, id_map, null, unique, **kwargs])

CSVファイルからテーブルに、データのインポートを行います。

>>> db.person.import_from_csv_file(open('test.csv', 'r'))
csvfile
インポートするCSVファイルを指定します。
id_map

CSVファイルに含まれる参照先id値を変更する場合に指定します。デフォルト値はNoneです。

>>> id_map = {'person':{'1':'11','2':'12','3':'13','4':'14','5':'15'}}
>>> db.dog.import_from_csv_file(open('test.csv','r'), id_map=id_map)
>>>                     # dogテーブルへのインポート時にpersonテーブルの参照値を変更
>>>                     # 参照値は 1->11, 2->12, 3->13, 4->14, 5->15 のように変更
null
null値(PythonではNone)の場合の代替文字列を指定します。デフォルトは <NULL> です。
unique
ユニークフィールドの指定です。デフォルト値は uuid です。
**kwargs

次のオプションを指定できます。

delimiter
フィールド区切り記号の指定です。デフォルトは’,’です。
quotechar
文字列を囲む記号の指定です。デフォルトは’”’です。
quoting

文字列囲み記号をどのようにつけていくか指定します。デフォルトは QUOTE_MINIMAL です。

  • QUOTE_ALL - 全フィールドをquotecharで囲む
  • QUOTE_MINIMAL - delimiter記号を含んだり、quotecharで始まるフィールドだけをquotecharで囲む
  • QUOTE_NONNUMERIC - 非数値フィールドだけをquotecharで囲む
  • QUOTE_NONE - quotecharで囲まない

参考: Python ライブラリリファレンス - 12.20 csv - 12.20.1 モジュールの内容

サンプルを使った説明は、 import_from_csv_fileメソッド(Tableクラス) も参照ください。

Table.on(query) → Expressionインスタンス

自分自身とパラメータを SQL の ON 句を挟んで、Expressionインスタンスにします。

>>> print db.person.on(db.person.id==db.dog.owner_id)
person ON (person.id = dog.owner_id)
query
条件式を指定します。
戻り値
Expressionインスタンス
Table.with_alias(alias) → Tableインスタンス
>>> print db.person.with_alias('person1')
person AS person1

テーブルの別名を設定します。これはjoin発行時などに使用します。SQL文変換では AS演算子になります。

alias
設定する別名です。
戻り値
別名セッテしたTableインスタンスのコピーです。

サンプル及び詳細な説明は、 自己参照型フィールドの注意点 を参照ください。

Table.fields() → リスト値

テーブルのフィールド一覧を返します。

>>> db.person.fields
['id', 'name']
戻り値
テーブルのフィールド一覧のリスト値
Table._insert(**fields) → SQL文
Table._drop([mode = '']) → SQL文
Table._truncate(mode = None) → SQL文

SQL文を返します。 SQL文の生成 も参照ください。

Table._enable_record_versioning([archive_db, archive_name, current_record, is_active])

テーブルのレコードバージョン管理を行います。詳細は、 レコードバージョン管理 を参照ください。

>>> db.person._enable_record_versioning()
archive_db
アーカイブテーブルを保存するデータベースを DAL インスタンスで指定します。 デフォルト値は None です。Noneの場合は、元の Table インスタンスのデータベースが使用されます。
archive_name
アーカイブテーブル名を指定します。デフォルトは、'%(tablename)s_archive' となります。 文字列フォーマット操作で指定します。
current_record
アーカイブテーブルの元のレコードを参照するフィールド名を指定します。 デフォルトは、'current_record' です。 指定した名前のフィールドがアーカイブテーブルに追加され、元のテーブルのレコードを参照するフィールドとして使用されます。
is_active
元のテーブルの有効/無効フラグ用フィールド名を指定します。デフォルトは、'is_active' です。

3.3.3. 特殊メソッド

Tableクラスには、いくつか特殊なメソッドが存在します。今回ここでは Tableインスタンスに対してフィールド名を辞書型で指定すると、 Field インスタンスを返す特殊メソッドを紹介します。これは DALクラスで説明した 特殊メソッド と同様の動きをします。

構文は次のようになります。

Tableインスタンス[フィールド名] → Fieldインスタンス

文字列のフィールド名を使って、Fieldインスタンスを取得する時などに使用出来ます。

サンプルは、アプリケーションの全テーブルに含まれるフィールドタイプが string のフィールドを抜き出します。

>>> for table in db.tables:
...     for field in db[table].fields:
...         if db[table][field].type == 'string':
...             print db[table]._tablename, db[table][field].name
auth_user first_name
auth_user last_name
auth_user email
auth_user registration_key
auth_user reset_password_key
auth_group role
auth_permission name
auth_permission table_name
::::::::::::

参考: Record Representationレコードの表現

3.3.4. 特殊メソッドによるショートカット機能

DAL概要の ショートカット でも紹介しましたが、Tableクラスには特殊メソッドによるショートカット 機能が実装されています。これについてはサンプルを紹介します。

参考: Shortcutsショートカット

リスト型へのエミュレーション

Tableインスタンスを、リスト型データのように扱えます。機能毎にサンプルを示します。

1.レコード挿入

Tableインスタンスにリスト型で0を指定し、辞書型でフィールド値を渡すと、レコードを追加します。

>>> db.person[0] = {'name':'Damasoco'}

>>> db.person[0] = dict(name='Damasoco')
これは次のコードと同等になります。
>>> db.person.insert(name='Damasoco')

2.レコード検索

Tableインスタンスにリスト型でidを指定すると、 Row インスタンスを返します。

>>> row = db.person[1]
これは次のコードと同等になります。
>>> row = db(db.person.id==1).select().first()

3.レコード更新

Tableインスタンスにリスト型でidを指定し、辞書型でフィールド値を渡すと、レコードを更新します。

>>> db.person[1] = {'name':'Damasoco'}

>>> db.person[1] = dict(name='Damasoco')
これは次のコードと同等になります。
>>> db(db.person.id==1).updaste(name='Damasoco')

4.レコード削除

リスト型でidを指定したTableインスタンスの先頭にコマンドのように del を付ければ 、指定idのレコードを削除します。

>>> del db.person[1]
これは次のコードと同等になります。
>>> db(db.person.id==1).delete()

関数へのエミュレーション

Tableインスタンスを関数のように呼び出すことが可能です。この場合、戻り値は Row インスタンス を返します。関数として呼び出す場合のレコード取得条件は、多様な方法で指定が可能です。

また該当する条件のレコードがない場合、Noneを返し例外は発生しません。このため リスト型へのエミュレーション よりも 安全に使用できます。

>>> row = db.person(1)                  # idフィールドが1のレコードを取得
>>> row = db.person(db.person.id==1)    # 条件式(Queryクラス)でレコードを取得
>>> row = db.person(name='Damasoco')    # パラメータでフィールドと値を指定してレコードを取得
>>> row = db.person(1,name='Damasoco')  # idとパラメータの2つの条件でレコードを取得
これは次のコードと同等になります。
>>> row = db(db.person.id==1).select().first()
>>> row = db(db.person.id==1).select().first()
>>> row = db(db.person.name=='Damasoco').select().first()
>>> row = db((db.person.id==1)&(db.person.name=='Damasoco')).select().first()

3.3.5. 属性

Table._common_filter

テーブルに設定された コモンフィルタ の属性値です。 この属性値を変更することによって、テーブルのコモンフィルタの設定変更が可能です。 Noneに変更するとコモンフィルタを無効にします。

Table._id

テーブルのキーの Field オブジェクトを保管します。 通常キーは id ですが、テーブルで違う名前のキーを使用している場合も _id を参照すればアクセス可能です。

Table._before_insert
Table._before_update
Table._before_delete
Table._after_insert
Table._after_update
Table._after_delete

コールバック関数をリスト値で設定します。詳細は コールバック関数 を参照ください。


[1]Pythonのinstance型オブジェクトではありませんが、簡単に説明するために インスタンス という言葉を使用しています。