多対多
□未翻訳
□翻訳中
■翻訳完了(細田謙二)
■レビュー(Omi Chiba)
多対多
前述の例では、1匹のdogは1人の所有者(owner)を持つけれど、1人のpersonは多くのdogsを持つようにしました。AlexとCurtによって所有されたSkipperはどうなるのでしょうか?これには多対多のリレーションが必要です。そしてこれは、所有(ownership)関係で1人のpersonと1匹のdogをリンクする中間テーブルを介して実現されます。
In the previous examples, we allowed a dog to have one owner but one person could have many dogs. What if Skipper was owned by Alex and Curt? This requires a many-to-many relation, and it is realized via an intermediate table that links a person to a dog via an ownership relation.
どのようにそれを行うかを以下に示します:
Here is how to do it:
これまでの所有(ownership)関係は次のように書き換えることができます:
the existing ownership relationship can now be rewritten as:
1.
2.
3.
>>> db.ownership.insert(person=1, dog=1) # Alex owns Skipper
>>> db.ownership.insert(person=1, dog=2) # Alex owns Snoopy
>>> db.ownership.insert(person=2, dog=3) # Bob owns Puppy
今度は、CurtがSkipperを共同所有するという新しいリレーションを加えることができます:
Now you can add the new relation that Curt co-owns Skipper:
1.
>>> db.ownership.insert(person=3, dog=1) # Curt owns Skipper too
3方向のテーブル間のリレーションを持っているので、操作を実行する上で、次のような新規のセットを定義するのは便利です:
Because you now have a three-way relation between tables, it may be convenient to define a new set on which to perform operations:
1.
2.
3.
>>> persons_and_dogs = db(
(db.person.id==db.ownership.person) \
& (db.dog.id==db.ownership.dog))
ここで、新規のSetからすべてのpersonsと彼らのdogsを選択するのは簡単です:
Now it is easy to select all persons and their dogs from the new Set:
1.
2.
3.
4.
5.
6.
>>> for row in persons_and_dogs.select():
print row.person.name, row.dog.name
Alex Skipper
Alex Snoopy
Bob Puppy
Curt Skipper
同様に、Alexが所有するすべてのdogsを検索することもできます:
Similarly, you can search for all dogs owned by Alex:
1.
2.
3.
4.
>>> for row in persons_and_dogs(db.person.name=='Alex').select():
print row.dog.name
Skipper
Snoopy
そして、Skipperの所有者も検索することができます:
and all owners of Skipper:
1.
2.
3.
4.
>>> for row in persons_and_dogs(db.dog.name=='Skipper').select():
print row.person.name
Alex
Curt
多対多への軽い代替案はタグ付けです。タグ付けはIS_IN_DBの文脈で後述します。タグ付けは、Google App EngineのようなJOINをサポートしていないデータベース・バックエンドでも機能します。
A lighter alternative to Many 2 Many relations is a tagging. Tagging is discussed in the context of the IS_IN_DB validator. Tagging works even on database backends that does not support JOINs like the Google App Engine.