4.3. ドキュメントでは触れなかった事項¶
今回のドキュメントで触れなかった事項は次の通りです。
4.3.1. インデックスの作成¶
web2py はインデックス作成はサポートしていません。直接データベースに作成してください。
またその場合、 executesql()
メソッドも利用可能です。
4.3.4. カスタムField型¶
カスタマイズした新しいフィールド型を定義できます。
4.3.5. テーブル定義なしでDALを使用¶
テーブル定義なしでDALを使用できます。これは外部のPythonプログラムなどで直接、DALにアクセスする場合などに使用します。
4.3.6. PostGIS、SpatiaLiteとMS Geo (実験的)¶
空間情報や地理に関するAPIです。
参考: PostGIS, SpatiaLite, and MS Geo (experimental) | PostGIS、SpatiaLiteとMS Geo (実験的)
4.3.7. 異なるdbからデータをコピー¶
web2pyは、新しいデータベースにデータをコピーするスクリプトを提供しています。
4.3.8. 新しいDALとアダプタの注意点¶
アダプタの作成のための、DALアダプタコードなどを紹介しています。
4.3.9. データベースの処方箋¶
各タイプのデータベースを使った場合の、制約などを説明しています。
参考: Gotchas | データベースの処方箋
web2py Book 日本語版では、なぜか「データベースの処方箋」が切れて表示されないようです。 以下、該当する部分の翻訳を掲載します。
データベースの処方箋
SQLiteはカラムの削除や置き換えをサポートしていません。これはweb2pyのマイグレーションがある程度まで機能することを意味します。テーブルからフィールドを削除した場合、そのカラムはデータベースには残るがweb2pyからは見えなくなります。もし、もう一度そのカラムを定義した場合は、web2pyは再作成を実行して失敗します。この場合、
fake_migrate=True
をセットすることでカラムを再度追加しないでメタデータを再構築できます。また同様の理由で、SQLiteはカラム型の変更に対応していません。文字フィールドに数字を挿入した場合、それは文字として格納されます。もし後でモデルを変更し型を"string"から"integer"に変更した場合、SQLiteはその数字を文字として保持し続けるため、データを抽出した際に問題になる可能性があります。MySQLはひとつのトランザクションによる、複数のALTER TABLEをサポートしません。これはマイグレーション処理が、複数のコミットに分割されることを意味します。もし何か失敗した場合に、マイグレーションがおかしくなる(web2pyメタデータが実際にテーブル構造と一致しなくなる)可能性があります。これは残念なことですが、その問題を防いだり(1度に1つずつのテーブルをマイグレーション)、
fake_migrate=True
をセットしてメタデータが再構築されてから、fake_migrate=False
をセットすることで、テーブルをもう一度マイグレーションすることで、事後修正(web2pyモデルをデータベースのテーブル構造に合わせるように戻す)することができます。Google SQLはMySQLと同様の問題に加えて、さらに問題を抱えています。具体的には、web2pyによってマイグレーションされていないテーブルメタデータ自身も、データベースのテーブルに格納される必要があります。これはGoogle App Engineが読み取り専用のファイルシステムだからです。上記のMySQLの問題と合わせたGoogle:SQLでのweb2pyマイグレーションはメータデータの破損をもたらす可能性があります。繰り返しなりますが、これは防いだり(1度に1つずつのテーブルをマイグレーションし、migrate=Falseをセットすることで、メタデータテーブルに接続されることがなくなる)、事後修正(Google ダッシュボードからデータベースに接続し、
web2py_filesystem
というテーブルに存在する破損した入力結果を削除する)することができます。MSSQLはOFFSETキーワードをサポートしません。このため、データベースはページネーションをすることができません。
limitby=(a,b)
をする場合、web2pyは最初にb
の行を取得しa
の行を破棄します。これは他のデータベースエンジンに比べてオーバーヘッドが大きくなる可能性があります。Oracleもページネーションをサポートしていません。また、OFFSETやLIMITキーワードもサポートしていません。web2pyはページネーションを実現しますが、
db(...).select(limitby=(a,b))
を複雑な3方向のネストしたselect(Oracleの公式ドキュメントで推奨されているように)に変換しています。簡単なselectの場合は、これで動作しますが、結合などをする複雑なselectの場合はおかしくなる可能性があります。MSSQLはONDELETE CASCADEを持つテーブルで循環参照をする際に問題があります。これはMSSQLのバグで、全ての参照フィールドのondelete属性にに"NO ACTION"をセットすることで回避できます。また、テーブルを定義する前に全てを一度に設定することもできます。
db = DAL('mssql://....') for key in ['reference','reference FK']: db._adapter.types[key]=db._adapter.types[key].replace( '%(on_delete_action)s','NO ACTION')MSSQLはDISTINCTキーワードに渡す引数の問題もあります。以下は動作しますが、
db(query).select(distinct=True)これは動作しません
db(query).select(distinct=db.mytable.myfield)Google NoSQL (Datastore)は結合、左外部結合、集計、式の使用、複数のテーブルの使用、like演算、"text"フィールドの検索が許可されていません。トランザクションも制限されているためweb2pyから自動で提供されません(オンラインのGoogle App Engine ドキュメントで説明されている、run_in_transaction
というGoogle APIを使用する必要があります)。また、1回のクエリで1度に取得できるレコード数も制限(執筆時点で1000レコード)されています。Google datastoreのレコードIDは整数型ですが連番ではありません。SQLでは"list:string"が"text"型にマッピングされますが、Google Datastoreでは、ListStringProperty
にマッピングされます。同様に、"list:integer"と"list:reference"は"ListProperty"にマッピングされます。これにより、SQLデータベースよりGoogle NoSQLの方がこれらのフィールド型の中身を検索する効率が良いです。