又是关于Google App Engine的问题。
根据GAE的官方文档,向GAE的存储区导入数据,导入了数次均出现问题,翻来覆去的无法成功。
CVS结构示例:1300428,浙江省嘉兴市,联通130卡 (一个手机号码的对应归属地列表)
configfile:
from google.appengine.ext import db
from google.appengine.tools.bulkloader import Loader
class MobilePhone(db.Model):
Number = db.StringProperty()
Area = db.StringProperty()
BrandType = db.StringProperty()
class MPLoader(Loader):
def __init__(self):
Loader.__init__(self, 'MobilePhone',
[('Number', unicode),
('Area', unicode),
('BrandType', unicode),
])
loaders = [MPLoader]
主要分析了一下,问题分为几类。
1.验证不能通过的问题:
这个问题很多时候是一个低级错误,之前我曾经犯过类似的错误。在app.yaml中的handlers
handlers:
- url: /remote_api
script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
login: admin
- url: /*
script: main.py
这个/*的配置必须放在最后。否则所有的访问都会直接匹配main.py自然出现问题。
2.跟编码有关的错误:
这个错误是GAE SDK的一个bug,恐怕对于ASCII系统的用户没什么关系,对于我们UTF-8,GB2312,ASCII已经昏倒的用户来说,这是个严重的问题。
在GAE的安装目录下 googleappenginetoolsbulkloader.py文件中2521行
for (name, converter), val in zip(self.__properties, values):
if converter is bool and val.lower() in ('0', 'false', 'no'):
val = False
properties[name] = converter(val)
修改为:
for (name, converter), val in zip(self.__properties, values):
if converter is bool and val.lower() in ('0', 'false', 'no'):
val = False
if isinstance(val,str) and not isinstance(val, unicode):
val=unicode(val,'utf-8')
properties[name] = converter(val)
系统会将unicode类型的变量转换。
3.对于大容量数据的删除
GAE的限制,一次最多载入1000行的数据,每次最多删除500行数据,这对于像我制作的手机号码归属之类的大数据库是远远不够的,多次删除又会导致500报错,我的方法是使用task queue。
Task Queue在官方的中文文档中没有提及,在英文文档中介绍的也不够详细。个人的理解就是让系统定期的去访问一个页面而已,我的例子:
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext import db
from google.appengine.api.labs import taskqueue
class MobilePhone(db.Model):
Number = db.StringProperty()
Area = db.StringProperty()
BrandType = db.StringProperty()
class Delete(webapp.RequestHandler):
def get(self):
q = db.GqlQuery("SELECT * FROM MobilePhone limit 100")
results = q.fetch(100)
db.delete(results)
q = db.GqlQuery("SELECT * FROM MobilePhone limit 100")
if (q.count() > 0):
self.addqueue()
self.response.out.write('Hello world!')
def addqueue(self):
taskurl = 'http://ip-and-mp.appspot.com/'
taskqueue.add( url='/del', params=dict(url=taskurl))
self.response.out.write('added!')
每次删除100行,使用默认的default queue,即每秒一次。
4.关于命令行的问题
我按照中文文档的办法始终有问题,添加了–email=xxxx –passin的参数才成功。手册已经远远落后了。


近期评论