在try-except-finally中的神秘行为

时间:2012-02-08 05:11:44

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

请原谅这个模糊的标题,我不知道如何陈述这一点。

我有一个任务工作者请求处理程序,它从URL中提取数据并将其写入blobstore,并将数据的blob_key保存到数据存储区中的ListProperty。为了清晰起见,我试图简化代码:

class Fetch(webapp2.RequestHandler):
    def get(self):

        url = self.request.get('url')
        itemKey = self.request.get('itemKey')
        item = MyModel.get(itemKey)

        try:
            result = urlfetch.fetch(url=url)
            if result.status_code == 200:
                saveDataResult = save_data(result.content, itemKey)
                if saveDataResult is False:
                    raise Exception('error saving data')
            else:
                raise Exception('error fetching data: %s' % result.status_code)

            item.status = 'success'
        except Exception:
            item.status = 'failed'
        finally:
            item.put()

def save_data(data, itemKey)
    try:
        #write data to blobstore and get its blob_key...
        blob_key = files.blobstore.get_blob_key(file_name)
        item = MyModel.get(itemKey)
        item.blobKey.append(blob_key)
        item.put()

        return True
    except:
        return False

现在我遇到的问题是,当saveDataResult返回True时,其状态设置为'success',但其blobKey属性不包含任何值,即使生成了blob_key并且数据已成功写入。我无法看到是什么原因导致我挽救生命,请帮忙。

3 个答案:

答案 0 :(得分:2)

如果没有更多信息,很难确定发生了什么。这是我受过教育的猜测:

MyModel.get(itemKey)get()中都会调用{p> save_data()。我猜测它正在返回两个代表该项目的不同对象。当blobKey在save_data中更新时,更新仅在save_data中提取的对象中发生。当您稍后在该范围之外检查它时,您正在查看另一个对象。

这是否正确取决于MyModel.get()的实施情况。

此外,您确实意识到您正在呼叫item.put()两次,对吗?

答案 1 :(得分:1)

问题出在这里

finally:
    item.put()

此单个调用会覆盖save_data()保存的数据,因为它引用了较旧的项目对象。

我的建议是你从save_data()进行状态更新,即item.status = 'success' 或者item = MyModel.get(itemKey)之后移动save_data(),以便您可以获取更新的对象。

答案 2 :(得分:0)

问题是当您使用save_data()致电item = MyModel.get(itemKey)时 再次从类Fetch调用你最终有两个不同的对象,因此覆盖save_data()中的一个,因此当你去你的模型数据存储区时,没有blobkey的数据存储为覆盖它。

尝试在课堂上做所有事情,或者不要两次使用item = MyModel.get(itemKey)