当子表引用父表时,web2py的DAL会自动创建转发引用吗?

时间:2012-08-03 19:50:20

标签: data-access-layer web2py

以下信息来自web2py book的第270页:

person = db.person(id)

for dog in person.dog.select(orderby=db.dog.name):
    print person.name, 'owns', dog.name

在最后一个表达式person.dog

的快捷方式
db(db.dog.owner==person.id)

现在:

本书没有引用定义person表的部分,我不相信该表的任何先前定义实际上有dog列。如果人员表确实有一个dog列,那就没有意义,因为大概是一个人可以有很多狗。

他们是否说某种方式从dog表到人的引用会自动创建从人到dog的前向引用,person中没有任何明确的列?

1 个答案:

答案 0 :(得分:1)

“person”数据库表本身没有自动创建任何内容。相反,表示给定人的记录的DAL Row对象包括DAL Set对象,该对象表示引用该人的“dog”表中的记录集。在代码中,person是一个Row对象(即db.person(id)) - 它有一个“dog”属性,它只是以下DAL Set对象:

db(db.dog.owner == person.id)

这是引用此人的狗的集合。如果你这样做:

>>> print db.person(1)

你会看到类似的东西:

<Row {'name': 'John', 'update_record': <function <lambda> at 0x2b08758>,
'dog': <gluon.dal.Set object at 0x2b00d10>, 'id': 1,
'delete_record': <function <lambda> at 0x2b08b90>}>

因此,除了包含记录的“name”和“id”值之外,Row对象还包括update_record()delete_record()函数以及表示“dog”表的Set对象引用此人的记录。如果打印与该Set对象关联的查询,则会得到以下内容:

>>> print db.person(1).dog.query
(dog.owner = 1)

因此,前向引用是在Row对象本身中创建的。注意,db.person(1).dog属性只是定义查询的Set对象 - 它不包含实际的“dog”表记录,甚至不包含对其id的引用。在通过select()调用db.person(1).dog.select()方法之前,不会对数据库进行任何查询,这将从“狗”表中返回实际记录。