以下信息来自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
中没有任何明确的列?
答案 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()
方法之前,不会对数据库进行任何查询,这将从“狗”表中返回实际记录。