我确实有我想要填充的以下GAE数据存储模型(models / location.py):
from google.appengine.ext import db
class Location(db.Model):
name = db.StringProperty(required=True)
country = db.StringProperty(required=False)
address = db.PostalAddressProperty(required=False)
coordinates = db.GeoPtProperty(required=False)
description = db.TextProperty(required=False)
为此,我创建了一个类LocationCreateHandler和一个函数_geocode(handlers / location.py):
from google.appengine.ext import db
from google.appengine.api import urlfetch
from webapp2_extras import json
import urllib
from handlers import BaseHandler
from models.location import Location
import logging
class LocationCreateHandler(BaseHandler):
def post(self):
name = self.request.get("name")
country = self.request.get("country")
address = self.request.get("address")
coordinates = _geocode(self, address)
description = self.request.get("description")
newLocation = Location(name=name, country=country, address=address, coordinates=coordinates, description=description)
newLocation.put()
return self.redirect("/location/create")
def get(self):
self.render_response("location/create.html")
def _geocode(self, address):
try:
logging.info("Geocode address: %s", address)
parameter = {'address': address.encode('utf-8'), 'sensor': 'false'}
payload = urllib.urlencode(parameter)
url = ('https://maps.googleapis.com/maps/api/geocode/json?%s' % payload)
logging.info("Geocode URL: %s", url)
result = urlfetch.fetch(url)
jsondata = json.decode(result.content)
location = jsondata['results'][0]['geometry']['location']
coordinates = '%s,%s' % (location['lat'], location['lng'])
logging.info("Geocode coordinates: %s", coordinates)
return coordinates
except:
return "0.0,0.0"
我如何使这种异步?目前,用户必须等到地理编码查找完成。 一旦我开始工作,我还计划在更新位置记录后使用_geocode()。
我还是要在“result =”之后找出_geocode部分,似乎是一个错误,因为我总是收到0.0,0.0。
-Luca。
答案 0 :(得分:1)
似乎很适合task queues。当POST到达时,启动任务,将其传递给Location实体的所有参数。然后,您可以完成请求并立即返回客户端。该任务可以调用_geocode,然后使用所有数据创建Location实体。
或者,如果由于某种原因需要在请求处理程序中创建Location对象,则可以在POST处理程序中执行此操作,并将新实体的键传递给该任务。任务完成后,它可以获取实体并使用坐标更新它。
另外,为了帮助确定你的urlfetch无法正常工作的原因,这里有一种记录异常的方法,同时仍然可以捕获它:
import traceback
try:
...
except:
logging.exception(traceback.print_exc())
答案 1 :(得分:1)
谢谢Jamie
我现在使用任务队列实现了GeocodeWorker(workers / googleapis.py):
from handlers import BaseHandler
import urllib
import logging
from google.appengine.api import urlfetch
from google.appengine.ext import db
from webapp2_extras import json
from models.location import Location
class GeocodeWorker(BaseHandler):
def post(self):
address = self.request.get('address')
logging.info("Geocode address: %s", address)
parameter = {'address': address.encode('utf-8'), 'sensor': 'false'}
url = ('https://maps.googleapis.com/maps/api/geocode/json?%s' % urllib.urlencode(parameter))
logging.info("Geocode URL: %s", url)
result = urlfetch.fetch(url)
JSONData = json.decode(result.content)
location = JSONData['results'][0]['geometry']['location']
coordinates = '%s,%s' % (location['lat'], location['lng'])
logging.info("Geocode coordinates: %s", coordinates)
key = self.request.get('key')
logging.info("Geocode key: %s", key)
existingLocation = Location.get(db.Key(key))
existingLocation.coordinates = coordinates
existingLocation.put()
我还修改了我的位置处理程序(handlers / location.py)来调用worker:
from google.appengine.api import taskqueue
from webapp2 import uri_for
class LocationCreateHandler(BaseHandler):
def get(self):
self.render_response('location/create.html')
def post(self):
name = self.request.get('name')
country = self.request.get('country')
address = self.request.get('address')
description = self.request.get('description')
newLocation = Location(name=name, country=country, address=address, description=description)
key = newLocation.put()
params = {'key': key, 'address': address}
taskqueue.add(url=uri_for('googleapis-geocode'), queue_name='googleapis', name=('googleapis-geocode-%s' % key), params=params)
return self.redirect('/location/create')
我还创建了一个queue.yaml文件,定义了googleapis队列。 我也删除了try:except:part。谷歌队列将自动重试该操作,并在定义的时间后退出。
您是否看到任何改进方面?
-Luca。