GAE的数据导入问题

又是关于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的安装目录下 google\appengine\tools\bulkloader.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的参数才成功。手册已经远远落后了。

推荐阅读:
去年的DCDC,我主要介绍了基
任何一个合理的应用程序的运行时
5月中旬,我参加了在加利福尼亚

发表评论

电子邮件地址不会被公开。 必填项已用*标注

请补全下列算式: *

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据