【问题标题】:GAE NDB AttributeError model instance has no attributeGAE NDB AttributeError 模型实例没有属性
【发布时间】:2015-02-19 11:04:18
【问题描述】:

我有一个名为“Bin”的 Google App Engine NDB 模型。 我已经修改了“Bin”的属性并删除了与旧模型对应的所有数据条目。我的目标是查询所有 bin 并访问 GAE Endpoints 函数中的属性“label”。但是,当查询和遍历返回的列表时,我得到AttributeError: 'Bin' object has no attribute 'label',这显然是错误的。日志输出显示返回的列表实际上包含两个 Bin 对象,它们具有名为“标签”的属性。

有趣的是,当我围绕查询更改代码时,代码将在下次运行时正常工作。然后又失败了。

我已清除内存缓存,重新启动应用引擎启动器并删除所有条目(然后添加新条目)以尝试删除任何缓存。

NDB 模型

class Bin(ndb.Model):
    id=ndb.IntegerProperty(required=True)
    label=ndb.StringProperty(required=True)
    items=ndb.JsonProperty()

查询

import endpoints
from protorpc import messages
from protorpc import message_types
from protorpc import remote
from includes.models import Bin
...
@endpoints.api(name='iwora', version='v1')
class Api(remote.Service):
    @endpoints.method(message_types.VoidMessage, BinCollection,
    path='bin', http_method='GET',
    name='bin.all')
    def bin_all(self, request):
        self.user_required()

        namespace = namespace_manager.get_namespace()
        try:
            namespace_manager.set_namespace(self.user.active_org)
            bins = Bin.query().fetch()
            logging.info('BINS: %s' % bins)
            binsresponse = []
            for bin in bins:
                logging.info('BIN: %s' % bin)
                obj = {
                    'label': bin.label # error happens here
                }
                binsresponse.append(obj)
        finally:
            namespace_manager.set_namespace(namespace)

        return BinCollection(bins=binsresponse)
...

当查询运行并尝试遍历返回的 bin 时,我得到以下输出:

BINS: [Bin(key=Key('Bin', 'default_bin', 'Bin', 5275456790069248), id=2L, items=None, label='1-1-2'), Bin(key=Key('Bin', 'default_bin', 'Bin', 5838406743490560), id=1L, items=None, label='1-1-1')] BIN: Bin(key=Key('Bin', 'default_bin', 'Bin', 5275456790069248), id=2L, items=None, label='1-1-2') 来自 ProtoRPC 方法实现的意外错误:AttributeError ('Bin' object has no attribute 'label') 回溯(最近一次通话最后): 文件“/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/protorpc-1.0/protorpc/wsgi/service.py”, 第 181 行,在 protorpc_service_app 中 响应 = 方法(实例,请求) 文件“/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine- default.bundle/Contents/Resources/google_appengine/lib/endpoints-1.0/endpoints/api_config.py", 第 1332 行,invoke_remote 返回远程方法(服务实例,请求) 文件“/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/protorpc-1.0/protorpc/remote.py”, 第 412 行,invoke_remote_method 响应 = 方法(服务实例,请求) bin_all 中的文件“/Users/rlfrahm/Apps/iwora/api.py”,第 524 行 “标签”:bin.label AttributeError: 'Bin' 对象没有属性 'label'

我认为(就像我相信的那样,但尚未确认)只有在我实现了一个模型、将条目添加到数据库中、然后通过更改属性名称或添加新属性来修改模型时才会发生这种情况。即使删除条目后,我仍然遇到此问题。我意识到这个问题在当前状态下是不可重复的,因为我不完全知道如何重现该错误。它似乎“刚刚发生”。我有许多其他功能使用相同的过程并且工作得很好。甚至 SDK Console 中的交互式控制台也能正确返回。

因此,我真的想知道是否有人看到过这种行为或发现我的流程有明显问题?

【问题讨论】:

  • 您清楚地向我们展示了您的代码的一部分(例如,您设置但从未使用 binsresponseobj)并且我怀疑损坏发生在您省略的部分中,使我们无法帮助您调试。请发布一个简洁的但完整的失败示例,可能使用testbed 使其真正独立...
  • 除了查看记录的第一行之外,您还可以看到检索到的每个 Bin 实例实际上都有一个标签属性。遍历 Bins 列表并以某种方式导致 ProtoRPC 调用的事实看起来很奇怪。你遗漏了很多信息。
  • @AlexMartelli - 我已经更新了描述。查询和迭代发生在 GAE Endpoints 函数中。除了这个函数之外,还有其他函数可以对不同的模型进行类似的查询,而且它们工作得很好。
  • @TimHoffman - 查询驻留在 GAE Endpoints 函数中。我已经用更多信息更新了操作。让我知道您还想知道什么。
  • @frahminator,我已经编辑了标签以包含您省略的 google-cloud-endpoints - 现在我可以尝试重现您的实际问题。

标签: python google-app-engine google-cloud-datastore google-cloud-endpoints


【解决方案1】:

这是我试图重现您的错误的最佳尝试——它包括您愿意与我们分享的所有稀疏代码片段,而且完全没有显示任何错误。

import logging
import webapp2
from google.appengine.ext import ndb

class Bin(ndb.Model):
    id=ndb.IntegerProperty(required=True)
    label=ndb.StringProperty(required=True)
    items=ndb.JsonProperty()

class MainHandler(webapp2.RequestHandler):
    def get(self):
        bins = Bin.query().fetch()
        if not bins:
            Bin(id=1L, items=None, label='1-1-1').put()
            Bin(id=2L, items=None, label='1-1-2').put()
            bins = Bin.query().fetch()
        logging.info('BINS: %s' % bins)
        binsresponse = []
        for bin in bins:
            logging.info('BIN: %s' % bin)
            obj = {
                'label': bin.label # error happens here
            }
            binsresponse.append(obj)

        self.response.write('Hello world! ')
        self.response.write(binsresponse)


app = webapp2.WSGIApplication([
    ('/', MainHandler)
], debug=True)

在 SDK 中本地运行显示,正如预期的那样:

Hello world! [{'label': u'1-1-2'}, {'label': u'1-1-1'}]

日志中相关的sn-p是:

INFO     2014-12-21 03:15:56,721 main.py:19] BINS: [Bin(key=Key('Bin', 5066549580791808), id=2, items=None, label=u'1-1-2'), Bin(key=Key('Bin', 5629499534213120), id=1, items=None, label=u'1-1-1')]
INFO     2014-12-21 03:15:56,721 main.py:22] BIN: Bin(key=Key('Bin', 5066549580791808), id=2, items=None, label=u'1-1-2')
INFO     2014-12-21 03:15:56,722 main.py:22] BIN: Bin(key=Key('Bin', 5629499534213120), id=1, items=None, label=u'1-1-1')

IOW,没问题。

添加到这个小代码(其中确实包括您打算发布的最后一点!-)缺少什么以使其重现您的错误,并编辑您的问题以包含最小的失败示例-- 否则,放弃所有希望任何人都能够帮助您调试错误的希望!-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-20
    相关资源
    最近更新 更多