问题描述
我正在将Google App Engine Python 2项目转换为Python 3
通过阅读文档,我的理解是我理解的首选路径是直接运行主python程序,就像过去一样跳过dev_appserver.py。
https://cloud.google.com/appengine/docs/standard/python3/tools/local-devserver-command
python3 main.py
--- main.py --
# coding: utf-8
import flask
from flask import request,redirect,url_for
from flask_basicauth import BasicAuth
#from urllib# import urlparse,urlunparse
import config
--- config.py
import model
...
33: CONFIG_DB = model.Config.get_master_db()
--- model/config.py
from __future__ import absolute_import
from google.cloud import ndb
#from oauth2client.contrib.appengine import CredentialsNDBProperty
from api import fields
import config
import model
import util
...
class Config(model.Base,model.ConfigAuth):
...
@classmethod
def get_master_db(cls):
57: return cls.get_or_insert('master')
运行以下跟踪时会产生
Traceback (most recent call last):
File "main.py",line 9,in <module>
import config
File "/home/ffej/cloudpayback/main/config.py",line 33,in <module>
CONFIG_DB = model.Config.get_master_db()
File "/home/ffej/cloudpayback/main/model/config.py",line 57,in get_master_db
return cls.get_or_insert('master')
File "/home/ffej/cloudpayback/env/lib/python3.8/site-packages/google/cloud/ndb/_options.py",line 89,in wrapper
return wrapped(*pass_args,**kwargs)
File "/home/ffej/cloudpayback/env/lib/python3.8/site-packages/google/cloud/ndb/utils.py",line 146,in positional_wrapper
return wrapped(*args,**kwds)
File "/home/ffej/cloudpayback/env/lib/python3.8/site-packages/google/cloud/ndb/model.py",line 5698,in _get_or_insert
return cls._get_or_insert_async(
File "/home/ffej/cloudpayback/env/lib/python3.8/site-packages/google/cloud/ndb/_options.py",line 5811,in _get_or_insert_async
key = key_module.Key(cls._get_kind(),name,parent=parent,**key_args)
File "/home/ffej/cloudpayback/env/lib/python3.8/site-packages/google/cloud/ndb/key.py",line 290,in __new__
context = context_module.get_context()
File "/home/ffej/cloudpayback/env/lib/python3.8/site-packages/google/cloud/ndb/context.py",line 96,in get_context
raise exceptions.ContextError()
google.cloud.ndb.exceptions.ContextError: No current context. NDB calls must be made in context established by google.cloud.ndb.Client.context.
迁移之后是否应该包含其他逻辑来启动/初始化数据存储?
谢谢, 杰夫
解决方法
Python3中NDB库的API发生了重大变化。要在localhost上进行开发,您必须:
-
运行DataStore Emulator,因为您不再运行dev_appserver:
$ gcloud beta emulators datastore start
-
如果使用the new NDB Library,则每个NDB操作都需要包装在上下文管理器中:
with ndb_client.context(): # <- you need this line
cls.get_or_insert('master')
编辑:您可以使用中间件,而不是使用上下文管理器包装每个NDB调用,而是将整个请求周期包装到NDB上下文中:
class NDBMiddleware:
def __init__(self,app):
self.app = app
self.client = ndb_client
def __call__(self,environ,start_response):
with self.client.context():
return self.app(environ,start_response)
app = Flask(__name__)
app.wsgi_app = NDBMiddleware(app.wsgi_app)