Google App Engine SDK Version 1.2.6更新

收取Email - 你的App Engine程序以前就可以发送Email了...但是现在,随着1.2.6版本的到来,你的程序可以实现接收email功能了。在起用mail作为Inbound服务(就像XMPP)以后,用户可以使用类似whatever@yourappid.appspotmail.com这样的地址给你的程序发送mail。Inbound信息被转变成一个你可以接收的webhook句柄HTTP请求(同样类似XMPP)。关于这部分的文档,Python版和Java版。

删除一个程序 - 我们的开发人员收到了很多希望实现删除不再使用的程序功能的请求(Top5的特性请求之一)。这一特性已经可以在管理后台实现!可以通过访问Application Settings页面获得更多信息,更多

数据库状态 - 你现在可以在管理后台看到程序数据的更多统计细节。这些信息也可以通过程序来访问,文档Python, Java

更多细节察看Release Notes

Google App Engine SDK Version 1.2.5更新

  • Python和Java的SDK版本更新到了1.2.5- 下载
  • App Engine现在可以通过XMPP协议来收发消息,支持和类似Jabber或者Google Talk这样的即时通讯服务进行通信。
  • Java SDK现在有测试Task Queue服务的API
  • Java SDK现在支持所有的内置数据类型,包括GData类型,比如GeoPt
  • JDO和JPA现在支持使用查询来删除实体
  • JDO现在可以使用makePersisitentAll()和deletePersistentAll()进行数据批处理操作
  • 数据实体的key现在可以使用数字开头,不再需要用户ID必须使用非数字字符来作为实体key的前缀
  • 数据transactions现在支持多次同步写入和删除实体在一个transaction过程中
  • URL Fetch请求现在能够设置Referer的Header。如果程序不设置header,将不对headers请求。此前,App Engine一直强制使用特定的App Engine header
  • Java程序现在可以使用java.net.URLConnection接口的setConnectionTimeout()为URL Fetch设置deadline
  • Java程序可以在开发环境的web.xml中使用元素调整MIME类型
  • Java程序可以使用appengine-web.xml文件控制浏览器缓存过期的时间
  • bulkloader加入了一个试验中的特性,可以删除和恢复每个实体而不需要加入任何代码和设置。目前这个特性仅仅在bulkloader.py工具中可用;这一功能将在稳定后被移动到appcfg.py工具中
  • Python SDK for Windows现在加入了图形化的接口来提供创建、测试和开发项目的功能。这一功能和Mac上的Launcher一样。Windows版本的启动器使用Python和wxWidgets开发,所以Linux用户也可以下载
  • 使用Python appcfg.py request_logs命令行,你现在可以调整log的日期来使用--end_date参数下载代码。而且文档已经加入了介绍以前版本的--include_vhost参数

Google App Engine SDK Version 1.2.4更新

[via]

GAE技术文章更新和一些新的开源项目

App Engine团队近日更新了App Engine文档中一些介绍程序扩展性的文章——编写可扩展性程序的最佳实践。此外,新的文档的分类也更加详细。

GeoModel开源项目

GeoModel是用来索引和查询的地理空间数据的一个开源项目,由Google Earth API的工程师Roman Nurrik发起。GeoModel使用称之为geocellsgeohash-like对象来进行索引和查询。GeoModel不仅优化了基本房地产搜索/商业定位,而且可以适用于大型的数据集。

使用GeoModel开发者可以通过继承GeoModel中的类迅速建立地理背景的数据模型。目前,数据实体可以与一个单一的地理坐标对应,随后索引和过滤符合周围地区或接近(最近n )到搜索中心点的坐标。

其他开源项目
  • GaeVFS,使用App Engine数据存储移植的Apache Commons VFS插件,使用了数据库和memcache APIs。
  • GraniteDS 2.0,支持App Engine for Java:Granite DS是一个为Java EE服务器开发的Adobe生命周期数据服务的替代品,支持服务器的推进和持续机制。更多信息请参考他们的announcement
  • jiql是基于JDBC的包装的应用程序引擎的低级别的数据存储的API,提供了开发人员熟悉的分布式数据库的接口。
  • pQg是基于PHP的从SQL到JDO的概念程序和一些范例

Google App Engine SDK Version 1.2.3更新

关于GAE你可能不知道的十件事

  • 程序版本号并不是number类型而是string
    尽管在多数的例子中都将app.yaml和appengine-web.xml中的'version'字段作为number类型,实际上这只是人们的一种习惯。程序版本可以是任何URL中允许的string类型。例如,你可以将你的版本设置成"live"和"dev",这样你就可以通过"live.latest.yourapp.appspot.com"和"dev.latest.yourapp.appspot.com"这样的地址来访问了。
  • 你可以在程序中同时使用多个版本
    这里有一点是很NB的,不同的版本可以使用不同的运行环境。换言之,你可以为你的程序开发使用Java语言的版本和Python语言的版本。
  • Java运行时支持任何编译成Java bytecode的语言
    这就是为什么人们需要Java runtime的原因,一旦这家伙被支持了就等于你可以在GAE上使用什么JRuby,Groovy,Scala,Rhino(JavaScript编译器),Quercus(PHP编译器),甚至Jython!
  • 使用'IN'和'!='运算符可以生成多重数据查询
    例如,查询"SELECT * FROM People WHERE name IN ('Bob', 'Jane')"将会被编译成两个查询等价于使用"SELECT * FROM People WHERE name = 'Bob'"和"SELECT * FROM People WHERE name = 'Jane'"并合并查询的结果。
    查询"SELECT * FROM People WHERE name IN ('Bob', 'Jane') AND age != 25"将会为每种可能生成生成查询,(age小于或者等于25, 和name是否为'Bob'或者'Jane'),然后将每种可能合并成结果。
  • 你可以使用批处理执行put,get和delete操作来提高效率。
    每当你做出一个数据请求,比如一个查询或者get()操作,你的程序将会对数据库发出请求,而数据库将会执行这些操作并返还一个response。请求到响应的循环过程将会花费一定时间,所以如果你执行的请求过多的话将会导致用户等待结果的时间过长(万恶的datastore timeout: operation took too long异常)。
    很幸运的是,GAE提供一个简单的方法来减少数据查询中的这种循环:批处理操作。db.put(),db.get(),和db.delete()函数都可以接受可选的list参数来执行操作。当一个传递一个list以后这些操作将会并行的遍历list的每一个元素,这样就大大节省了操作的时间。例如:
    for entity in MyModel.all().filter("color =",
        old_favorite).fetch(100):
      entity.color = new_favorite
      entity.put()
    
    更新操作需要一个数据库往返的查询,还需要加上一次操作来更新数据库中实体的属性————也就是说一共需要101次的往返!再看下面的例子:
    updated = []
    for entity in MyModel.all().filter("color =",
        old_favorite).fetch(100):
      entity.color = new_favorite
      updated.append(entity)
    db.put(updated)
    
    这个例子中只需要2次数据库往返,也就是说我们将101次往返减少到了2次。
  • 数据库的性能并不取决于其中实体的数量
  • 建立索引的时间开销并不全部取决于它的大小
  • 'Stored Data'的值是按日更新的
  • app.yaml,web.xml和appengine-web.xml中指明了项目的处理顺序
    人们经常犯的一个错误是忘记配置程序处理文件的顺序是自上而下的。比如,当使用remote_api时候很多人这样做:
    handlers:
    - url: /.*
      script: request.py
    
    - url: /remote_api
      script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
      login: admin
    
    上面的例子看起来没有什么问题,但是由于handler是按照顺序处理的,request.py是首先出现的,而所有请求包括对remote_api的请求都是使用request.py处理的。由于request.py加载后并没有出现remote_api,所以就会造成a 404 Not Found error的错误。解决的方法是将request.py的handler放置到remote_api的handler下面。在Java环境的配置文件中也是一样。
  • 你不需要手动构造GQL字符
    下面是一个反例:
    q = db.GqlQuery("SELECT * FROM People "
        "WHERE first_name = '" + first_name 
        + "' AND last_name = '" + last_name + "'")
    
    很幸运,GAE支持在GqlQuery语句中使用参数替换,上面例子可以改写成:
    q = db.GqlQuery("SELECT * FROM People "
        "WHERE first_name = :1 "
        "AND last_name = :2", first_name, last_name)
    
    GqlQuery还支持使用name来代替数字参数:
    q = db.GqlQuery("SELECT * FROM People "
        "WHERE first_name = :first_name "
        "AND last_name = :last_name", 
        first_name=first_name, last_name=last_name)
    
    这样做出了能使代码看起来更加简洁以外,还可以进行一些优化。如果你需要使用不同的值来进行多次同样的查询,你可以使用bind()函数来为每个查询重新绑定参数。这比起每次都要构造新的查询更加快捷,因为查询只需要分析一次:
    q = db.GqlQuery("SELECT * FROM People "
        "WHERE first_name = :first_name "
        "AND last_name = :last_name")
    for first, last in people:
      q.bind(first, last)
      person = q.get()
      print person
    

作者Nick Johnson, App Engine Team[via]

Google App Engine SDK Version 1.2.2发布

  • 新的quota API将当前请求转向CPU使用
  • Urlfetch开始支持自定义deadlines
  • SDK中的Urlfetch允许设置在header中设置Encoding来匹配appengine
  • urllib现在增添了对https支持
  • 数据库的indexes现在可以通过设置在属性构造函数中设置indexed=False来禁用
  • 数据库api支持Key-only查询,或者使用SELECT __key__ or db.Query(Model, keys_only=True)
  • 修复IN关键字的筛选和排序问题
  • 修复开发服务器控制台(/_ah/admin/datastore)当某属性是NoneType时不能显示的问题
  • Bulk Loader改进:新的appcfg下载数据命令,更好的后台支持和debug长请求输出
  • appcfg中新增参数--vhost会为特定的host选择记录
  • 可以通过import导入Python的_ast模块
  • 修复Images API颜色参数问题

另外最近还加入了web2py的支持,不过依然是不支持管理后台数据库等等,总之和django一样反正是你什么用的顺手就不支持什么。

wow-dkp-engine笔记:数据库中文编码问题及其他

先前我需要处理的问题是生成一个类似这个连接的表格,由于这个表格的各项数据是直接从数据库提取数据计算出来然后在提交给Google Visualization API,最后返还结果。这样做最大的弊端是如果数据比较多的情况下会引发一个datastore timeout: operation took too long的异常,于是我重写了这个程序把计算的结果变成一个数据库,这样做就避免了引发这个异常的问题。

使用正则表达式匹配中英文字符

这个问题也困扰了我很长时间。我需要从类似:


MiDKPData = {};
MiDKPData["dkp"] = {};


MiDKPData["dkp"][1] = {};
MiDKPData["dkp"][1]["name"] = "开心圈圈DKP";
MiDKPData["dkp"][1]["members"] = {};
MiDKPData["dkp"][1]["members"]["Donesee"] = 5;
MiDKPData["dkp"][1]["members"]["Latrogue"] = 0;
MiDKPData["dkp"][1]["members"]["Longwalker"] = 15;
MiDKPData["dkp"][1]["members"]["Lovelace"] = 56;
MiDKPData["dkp"][1]["members"]["Lucid"] = 232;
MiDKPData["dkp"][1]["members"]["Mitnick"] = 0;
MiDKPData["dkp"][1]["members"]["Neverlose"] = 33;
MiDKPData["dkp"][1]["members"]["Ooxxoo"] = 10;
MiDKPData["dkp"][1]["members"]["Shadowghost"] = 3;
MiDKPData["dkp"][1]["members"]["Steafinie"] = 14;
MiDKPData["dkp"][1]["members"]["一脸猥琐"] = 5;
MiDKPData["dkp"][1]["members"]["三聚氰胺"] = 31;
MiDKPData["dkp"][1]["members"]["人生真谛"] = 20;
MiDKPData["dkp"][1]["members"]["伟大的乌瑟尔"] = 5;
MiDKPData["dkp"][1]["members"]["光之留香"] = 73;

这样的数据中提取字符,这应该是Lua中数据类型。开始我考虑用处理字符串的方法提取,但经过测试效率很低而且容易出错。然后我尝试使用正则表达式匹配这些数据,使用正则表达式匹配的话需要对里面可能出现的中文进行匹配,该文件正常情况下应该是采用UTF-8编码。

def retext(data):
    data = data.split('\n')
    dict0 = {}
    for li in data:
        m = re.match(r"(\[\")(\w+|[\x80-\xff]+|[\u3400-\u9FFF]+)(\"\]\s\=\s)(\d+)(\;)",li)
        try:
            dict0[m.group(3)]=m.group(5)
        except AttributeError:
            pass
    return dict0

retext()中的[\x80-\xff]+可以匹配任意长度的UTF-8编码的中文,而[\u3400-\u9FFF]+可以匹配任意长度的unicode编码中文。我在函数中加入了对unicode编码进行匹配的原因是我需要处理的这个字符串是通过request.POST.get()发送到服务器的。而这个request.POST.get()正是使用unicode编码。如果在数据库中查询这些数据则还需要使用decode('utf-8')将字符转化成UTF-8编码。

数据对象key_name属性

设置数据库字段的key_name属性:如果某些字符串和数据库的对象是一一对应的,而这些字符串刚好又符合设置成key_name的条件,那么把这些字符串设置成key_name属性会方便许多

Google App Engine SDK Version 1.2.1更新

Google App Engine SDK Version 1.2.0发布

  • Cron支持。Appcfg.py将会上传在App Engine中执行的计划任务。开发环境的后台/_ah/admin对设置的计划任务进行描述但并不会执行,更多内容参考cron
  • 新的allow_skipped_files标记可以使开发服务器读取App Engine中不可用的文件。
  • appcfg提供新的upload_data命令行来运行bulk uploader,更多内容

1 2 NEXT
Creative Commons 3.0 BY