自己参照と別名

□未翻訳

□翻訳中

■翻訳完了(細田謙二)

■レビュー(Omi Chiba)

自己参照と別名

自分自身を参照するフィールドを持つテーブルを定義することも可能ですが、通常の表記方法ではうまくいきません。次のコードは。db.person変数を定義する前に用いているので間違っています:

It is possible to define tables with fields that refer to themselves although the usual notation may fail. The following code would be wrong because it uses a variable db.person before it is defined:

1.

2.

3.

4.

db.define_table('person',

Field('name'),

Field('father_id', db.person),

Field('mother_id', db.person))

解決策は次のような代替表記を使用することです

The solution consists of using an alternate notation

1.

2.

3.

4.

db.define_table('person',

Field('name'),

Field('father_id', 'reference person'),

Field('mother_id', 'reference person'))

実際、db.tablenameと"reference tablename"は同じフィールドの型になります。

In fact db.tablename and "reference tablename" are equivalent field types.

テーブルが自分自身を参照する場合、SQLの"AS"キーワードの使用なしに、JOINを実行して、personとその親(parents)を選択することは不可能です。これは、web2pyにおいてwith_aliasを用いて実現されます。以下がその例です。

If the table refers to itself, then it is not possible to perform a JOIN to select a person and its parents without use of the SQL "AS" keyword. This is achieved in web2py using thewith_alias. Here is an example:

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

14.

15.

16.

>>> Father = db.person.with_alias('father')

>>> Mother = db.person.with_alias('mother')

>>> db.person.insert(name='Massimo')

1

>>> db.person.insert(name='Claudia')

2

>>> db.person.insert(name='Marco', father_id=1, mother_id=2)

3

>>> rows = db().select(db.person.name, Father.name, Mother.name,

left=(Father.on(Father.id==db.person.father_id),

Mother.on(Mother.id==db.person.mother_id)))

>>> for row in rows:

print row.person.name, row.father.name, row.mother.name

Massimo None None

Claudia None None

Marco Massimo Claudia

以下のものを区別して選択していることに注意してください:

Notice that we have chosen to make a distinction between:

  • "father_id": "person"テーブルにおいて使用されるフィールド名

  • the field name used in the table "person";

  • "father": 上記のフィールドによって参照されるテーブルのために使用する別名。これはデータベースとやり取りされます。

  • the alias we want to use for the table referenced by the above field; this is communicated to the database;

  • "Father": その別名を参照するためのweb2pyによって使用される変数

  • the variable used by web2py to refer to that alias.

違いは僅かで、それら3つに同じ名前をつけても間違いではありません:

The difference is subtle, and there is nothing wrong in using the same name for the three of them:

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

14.

15.

16.

17.

18.

19.

20.

db.define_table('person',

Field('name'),

Field('father', 'reference person'),

Field('mother', 'reference person'))

>>> father = db.person.with_alias('father')

>>> mother = db.person.with_alias('mother')

>>> db.person.insert(name='Massimo')

1

>>> db.person.insert(name='Claudia')

2

>>> db.person.insert(name='Marco', father=1, mother=2)

3

>>> rows = db().select(db.person.name, father.name, mother.name,

left=(father.on(father.id==db.person.father),

mother.on(mother.id==db.person.mother)))

>>> for row in rows:

print row.person.name, row.father.name, row.mother.name

Massimo None None

Claudia None None

Marco Massimo Claudia

しかし、正しいクエリを構築するには、この区別を明確にすることが重要です。

But it is important to have the distinction clear in order to build correct queries.