.. meta:: :keywords: web2py, framework, DAL, データベース抽象化レイヤ, クラス, 主要クラス クラス ====== DALを使うには構成するクラスを知る必要があります。これらのクラスについて説明します。 .. _class_principal: 主要なクラス ------------ DALには非常に多くのクラスが含まれます。この中にはフレームワークを利用する上で、どうしても知っている必要があるクラスがあります。このようなクラスを次に挙げてみます。 ========== ================================ = クラス 説明 詳細説明 ========== ================================ = DAL データベースに関するクラス :ref:`class_dal` Field フィールドに関するクラス :ref:`class_field` Table テーブルに関するクラス :ref:`class_table` Query 条件式に関するクラス :ref:`class_query` Expression 式に関するクラス :ref:`class_expression` Set レコードセット定義に関するクラス :ref:`class_set` Rows レコードセットに関するクラス :ref:`class_rows` Row レコードに関するクラス :ref:`class_row` ========== ================================ = これらのクラスとその主な機能(メソッド)を表したのが次の図になります。 .. include:: ../class/class_diagrams/class_all.html クラスとそのクラスに属する機能(メソッド)を知るのは、DALを使いこなす上で重要な事項になります。 .. _syntax_dal_class: DAL構文とクラスの関係 --------------------- 次にDAL構文とクラスの関係について、サンプルコードを使って示してみます。 データベース接続 ^^^^^^^^^^^^^^^^ サンプルコード :: >>> db = DAL('sqlite://storage.db') サンプルとクラスの関連図 .. image:: ../../images/web2py_dal/web2py_dal_002r.JPG テーブル定義 ^^^^^^^^^^^^ サンプルコード :: >>> db.define_table('person', ... Field('name'), format='%(name)s') サンプルとクラスの関連図 .. image:: ../../images/web2py_dal/web2py_dal_003r.JPG レコード検索と出力 ^^^^^^^^^^^^^^^^^^ サンプルコード :: >>> rows = db(db.person.id > 0).select() >>> for row in rows: ... print row.name ... Potamata Cotasata Tamodama サンプルとクラスの関連図 .. image:: ../../images/web2py_dal/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構文とクラスは密接に関係しているということが、理解できるのではないでしょうか。 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 詳細は、 :ref:`class_dal` , :ref:`class_table` , :ref:`class_field` を参照ください。 .. _query_and_expression: QueryとExpression クラスについて -------------------------------- | QueryとExpressionと2つのクラスがありますが、Queryは条件式、Expressionは式に関するクラスです。 | 具体的に示してみます。 Queryクラス :: >>> qry = db.person.name == 'Potamata' # personのnameが'Potamata'とイコールという条件式 >>> type(qry) qryはQueryインスタンスになります。 Expressionクラス :: >>> exp = db.item.unit_cost * 1.1 # コスト単価を1.1倍にする式 >>> type(exp) expはExpressionインスタンスです。 これらのインスタンスは、他のクラスのメソッドなどの引数として使用することになります。 またExpressionクラスは、Queryクラスを返すメソッドを幾つか持っています。 サンプルコード :: >>> qry = db.person.name.like('P%') >>> type(qry) db.person.nameはFieldクラスですが、FieldクラスはExpressionクラスを継承しています。このためExpressionクラスのメッソド like の呼び出しが可能です。likeメソッドは、あいまい検索のQueryインスタンスを返します。 詳細は、 :ref:`class_query` , :ref:`class_expression` を参照ください。 .. _set_rows_row: Set Rows Row クラスについて --------------------------- Set Rows Row の各クラスは具体的に、どんなクラスなのでしょうか。この3つのクラスを説明したのが次の図です。 .. figure:: ../../images/web2py_dal/web2py_dal_005r.PNG :width: 90% 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) 文字列 ================ =============== | 詳細は、 :ref:`class_set` , :ref:`class_rows` , :ref:`class_row` を参照ください。