Нет текущей контекстной ошибки после миграции на Python 3, должен ли я включать больше логики?

#python-3.x #google-app-engine #google-cloud-platform #google-cloud-datastore #google-app-engine-python

#python-3.x #google-app-engine #google-cloud-platform #google-cloud-хранилище данных #google-app-engine-python

Вопрос:

Я конвертирую проект 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 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 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.
  

Есть ли дополнительная логика, которая должна быть включена после миграции для запуска / инициализации хранилища данных?

Спасибо, Джефф

Комментарии:

1. Как model.Config выглядит? Это то, что, похоже, вызывает ошибку.

2. спасибо за комментарий, я попытался немного перечислить.

Ответ №1:

API для библиотеки NDB в Python3 значительно изменился. Для разработки на localhost вам необходимо:

  • запустите эмулятор хранилища данных, поскольку вы больше не используете dev_appserver:

    $ gcloud beta emulators datastore start

  • если вы используете новую библиотеку NDB, то каждая операция 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)
  

Комментарии:

1. Этот код не работает, рабочая версия здесь: github.com/googleapis/python-ndb/issues /…

2. @SuatAtanPhD код промежуточного программного обеспечения идентичен коду github, который вы связали, и он работает для меня, поэтому, пожалуйста, не могли бы вы уточнить, что именно не работает?