在GAE上使用Python 2.7的注意事项
- ndv - keakon的涂鸦馆随着GAE SDK 1.5.5版的发布,开发者终于可以使用Python 2.7了. 不过今天我试用了一下,发现了一些需要注意的问题,于是记录在此. 它目前还是个实验性质的runtime,因此还没法本地测试,必须部署到云端. 它只支持HR datastore,不符合条件的需要迁移数据. 一些库的版本变了,在app.yaml的libraries部分可以配置.
try:
import json
except ImportError:
import simplejson as json
或者判断runtime版本:if os.environ['APPENGINE_RUNTIME'] == 'python27':
import json
else:
import simplejson as json
request_arrive_time = 0
db_count = 0
db_time = 0
db_start_time = 0
def before_db(service, call, request, response):
global db_count, db_start_time
db_count += 1
db_start_time = time()
def after_db(service, call, request, response):
global db_time
dt = time() - db_start_time
db_time += dt
apiproxy_stub_map.apiproxy.GetPreCallHooks().Append('before_db', before_db, 'datastore_v3')
apiproxy_stub_map.apiproxy.GetPostCallHooks().Push('after_db', after_db, 'datastore_v3')
blog.py:def main():
hook.db_count = 0
hook.db_time = 0
hook.db_start_time = 0
hook.request_arrive_time = time()
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
我在hook.py中使用了4个全局变量,如果在并发方式下,这种实现方式就可能会记录下错误的数据。class WsgiApplication(yui.WsgiApplication):
def __call__(self, environ, start_response):
local.request_arrive_time = time()
local.db_count = 0
local.db_time = 0
local.db_start_time = 0
return super(WsgiApplication, self).__call__(environ, start_response)
local = threading.local()
local.request_arrive_time = 0
local.db_count = 0
local.db_time = 0
local.db_start_time = 0
def before_db(service, call, request, response):
if hasattr(local, 'db_count'):
local.db_count += 1
else:
local.db_count = 1
local.db_start_time = time()
def after_db(service, call, request, response):
if hasattr(local, 'db_start_time') and hasattr(local, 'db_time'):
dt = time() - local.db_start_time
local.db_time += dt
先说threading.local(),它会生成一个线程安全的local对象。def hook_app(app):
def wrap(environ, start_response):
local.request_arrive_time = time()
local.db_count = 0
local.db_time = 0
local.db_start_time = 0
return app(environ, start_response)
return wrap
而在blog.py中还需要手动封装一下:application = hook.hook_app(application)