3.3. Table¶
Tableはデータベーステーブルに関するクラスです。メソッドはレコード挿入・テーブル削除などの、レコード・テーブル操作機能を持っています。
レコードの検索・更新・削除の機能は、 Set が受け持っています。ただ Tableクラスも特殊 メソッドの機能によって限定的ですが、レコード検索・更新・削除機能を利用できます。
Tableクラス — テーブルに関するクラス | |
---|---|
レコードの追加 | |
レコードをまとめて追加 | |
レコード更新or追加 | |
バリデータとレコード追加 | |
全レコードの削除 | |
テーブルの削除 | |
CSVファイルからのインポート | |
テーブル別名設定 | |
テーブルのフィールド一覧 | |
SQL文生成 | |
SQL文生成 | |
SQL文生成 | |
レコードバージョン管理 | |
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番号です。
-
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)では、大幅な高速化が期待できます。
-
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カウンタのリセットを指定します。
-
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で囲まない
サンプルを使った説明は、 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.
_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クラスには特殊メソッドによるショートカット 機能が実装されています。これについてはサンプルを紹介します。
リスト型へのエミュレーション¶
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.
_before_insert
¶
-
Table.
_before_update
¶
-
Table.
_before_delete
¶
-
Table.
_after_insert
¶
-
Table.
_after_update
¶
[1] | Pythonのinstance型オブジェクトではありませんが、簡単に説明するために インスタンス という言葉を使用しています。 |