try- except-finally 中的神秘行为
请原谅这个含糊的标题,我不知道还能用什么方式来表达这一点。
我有一个任务工作线程请求处理程序,它从 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 时,其状态设置为“成功”,但其 blobKey 属性不包含任何值,即使生成了 blob_key 并且数据写入成功。我不明白是什么导致了这拯救了我的生命,请帮忙。
Excuse the vague title, I didn't know how else to state this.
I have a task worker request handler that fetches data from a URL and writes it to blobstore and saves the data's blob_key to a ListProperty in datastore. I've tried to simplifly the code for clarity here:
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
Now the problem I'm having is, when saveDataResult returns True, its status is set to 'success' but its blobKey property contains no value, even though a blob_key was generated and the data successfully written. I can't see what's causing this to save my life, please help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果没有更多信息,很难确定发生了什么。这是我有根据的猜测:
MyModel.get(itemKey)
在get()
和save_data()
中都被调用。我推测它返回两个代表该项目的不同对象。当 blobKey 在save_data
中更新时,更新仅发生在save_data
中获取的对象中。当您稍后在该范围之外检查它时,您将看到一个不同的对象。这是否正确将取决于
MyModel.get()
的实现。另外,您确实意识到您调用了
item.put()
两次,对吗?Without much more information it is very difficult to determine what's happening. Here's my educated guess:
MyModel.get(itemKey)
is called both inget()
andsave_data()
. I surmise that it's returning two different objects representing the item. When the blobKey gets updated insave_data
, the update is occurring only in the object fetched insave_data
. When you later examine it outside that scope, you're looking at a different object.Whether this is correct or not will depend on the implementation of
MyModel.get()
.Also, you do realize that you're calling
item.put()
twice, right?问题在于,
这个单一调用会覆盖
save_data()
保存的数据,因为它引用了较旧的 item 对象。我的建议是您从
save_data()
进行状态更新,即item.status = 'success'
或者将
item = MyModel.get(itemKey)
移至save_data()
之后,以便您可以获取更新后的对象。The problem is here
this single call overrides the data saved by
save_data()
because it references an older object of item.My suggestion would be you do the status updates from
save_data()
i.eitem.status = 'success'
or move
item = MyModel.get(itemKey)
to come aftersave_data()
so you can fetch the updated object.问题是,当您使用
item = MyModel.get(itemKey)
调用save_data()
时再次从类 Fetch 中调用它,您最终会得到两个不同的对象,因此会覆盖 save_data() 中的一个,因此当您转到模型数据存储时,不会存储 blobkey 的数据,因为它被覆盖了。
尝试执行类中的所有操作,否则不要使用
item = MyModel.get(itemKey)
两次。The problem is that when you call
save_data()
withitem = MyModel.get(itemKey)
which is again called from the class Fetch you end up having two different objects and therefore overwriting the one in save_data() and hence when you go to your model datastore no data for blobkey is stored as its overwritten.
Try doing everything in the class or you do not use
item = MyModel.get(itemKey)
twice.