在GAE中利用Datastore的ReferenceProperty实现外键
三月 30th, 2009 | 426 次阅读
在GAE中,是没有提供关系式数据库的,只有Datastore:一种以db.Model为基本单元的数据库,这样子,就不能再GAE上面使用我们熟悉的外键来讲两个表进行连接了(呃~其实在Datastore里面也没有表)。
现在,让我们来看一段代码:
01 from google.appengine.ext import db
02
03 class Bus(db.Model):
04 number = db.StringProperty(required=True)
05 name = db.StringProperty(required=True)
06
07 class BusInfo(db.Model):
08 date = db.DateProperty(required=False)
09 time = db.TimeProperty(required=True)
10 bus = db.ReferenceProperty(Bus)
11 price = db.IntegerProperty(required=True)
02
03 class Bus(db.Model):
04 number = db.StringProperty(required=True)
05 name = db.StringProperty(required=True)
06
07 class BusInfo(db.Model):
08 date = db.DateProperty(required=False)
09 time = db.TimeProperty(required=True)
10 bus = db.ReferenceProperty(Bus)
11 price = db.IntegerProperty(required=True)
上面的代码构造了两个Model类,Bus里面存储了两个字符串数据:number和name。BusInfo则存储了日期数据date、时间数据time和整数数据price,同时还有一个Reference数据bus,这个Reference就是所对应的Bus实体的引用。
于是我们可以写出这样的代码:
01 import wsgiref.handlers
02 from models import BusInfo
03 from google.appengine.ext import db
04
05 class InfoHandler(webapp.RequestHandler):
06 def get(self):
07 values = {}
08 businfo = db.GqlQuery('SELECT * FROM BusInfo ORDER BY time ASC LIMIT 1').get()
09 values['businfo']= businfo
10 valuse['bus']= businfo.bus
11 self.response.out.write(template.render('info.html',values))
02 from models import BusInfo
03 from google.appengine.ext import db
04
05 class InfoHandler(webapp.RequestHandler):
06 def get(self):
07 values = {}
08 businfo = db.GqlQuery('SELECT * FROM BusInfo ORDER BY time ASC LIMIT 1').get()
09 values['businfo']= businfo
10 valuse['bus']= businfo.bus
11 self.response.out.write(template.render('info.html',values))
这样子,就直接可以从BusInfo实体中获取一个Bus实体。其原理在于,BusInfo中的bus是一个ReferenceProperty属性,其指向的是一个Key,而Key这个玩意在Datastore中扮演了一个非常重要的角色,它是一个实体的ID标识,根据一个实体的Key值,我们就可以获取这个实体,下面用两段代码演示:
1 if action == "delete":
2 id = self.request.get("id")
3 key = db.Key(id) #建立一个Key对象
4 query = Bus.all() #建立一个搜索所有Bus数据的query
5 bus = query.ancestor(key).get() #使用key对象来获取实体
6 if bus:
7 bus.delete()
8 self.redirect('/admin/bus')
2 id = self.request.get("id")
3 key = db.Key(id) #建立一个Key对象
4 query = Bus.all() #建立一个搜索所有Bus数据的query
5 bus = query.ancestor(key).get() #使用key对象来获取实体
6 if bus:
7 bus.delete()
8 self.redirect('/admin/bus')
1 def makeBusInfo(params):
2 busid = params.get("bus")
3 buskey = db.Key(busid)
4 businfo = BusInfo(bus=buskey,date=params.get('date'),
5 time=params.get('time'),
6 price=params.get('price'))
7 businfo.put()
8 return True
2 busid = params.get("bus")
3 buskey = db.Key(busid)
4 businfo = BusInfo(bus=buskey,date=params.get('date'),
5 time=params.get('time'),
6 price=params.get('price'))
7 businfo.put()
8 return True
如果你还是感到实在不好理解的话,可以尝试着把Key当作是db.Model的父类(虽然这样做很不严谨)。