我有一个在blobstore中创建blob的管道,并将生成的blob_key放在其named outputs之一中。当我通过我围绕它构建的Web界面运行管道时,一切都运行得非常好。现在我想创建一个小测试用例,它将执行这个管道,从blobstore中读取blob,并将其存储到磁盘上其他位置的临时位置,以便我可以检查它。 (因为testbed.init_files_stub()
仅在测试的生命周期内将blob存储在内存中。)
测试用例中的管道似乎工作正常,并且导致看起来像有效的blob_key,但是当我将该blob_key传递给blobstore.BlobReader
类时,由于某种原因它无法找到blob。从回溯中,似乎BlobReader正在尝试访问真正的 blobstore,而编写器(在管道内)正在写入 stubbed blobstore。我在dev_appserver.py上设置了--blobstore_path
,并且我没有看到测试用例将任何blob写入磁盘,但是当我从Web界面运行它时,blob会显示在那里。
这是追溯:
Traceback (most recent call last):
File "/Users/mattfaus/dev/webapp/coach_resources/student_use_data_report_test.py", line 138, in test_serial_pipeline
self.write_out_blob(stage.outputs.xlsx_blob_key)
File "/Users/mattfaus/dev/webapp/coach_resources/student_use_data_report_test.py", line 125, in write_out_blob
writer.write(reader.read())
File "/Users/mattfaus/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/blobstore/blobstore.py", line 837, in read
self.__fill_buffer(size)
File "/Users/mattfaus/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/blobstore/blobstore.py", line 809, in __fill_buffer
self.__position + read_size - 1)
File "/Users/mattfaus/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/blobstore/blobstore.py", line 657, in fetch_data
return rpc.get_result()
File "/Users/mattfaus/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 604, in get_result
return self.__get_result_hook(self)
File "/Users/mattfaus/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/blobstore/blobstore.py", line 232, in _get_result_hook
raise _ToBlobstoreError(err)
BlobNotFoundError
这是我的测试代码:
def write_out_blob(self, blob_key, save_path='/tmp/blob.xlsx'):
"""Reads a blob from the blobstore and writes it out to the file."""
print str(blob_key)
# blob_info = blobstore.BlobInfo.get(str(blob_key)) # Returns None
# reader = blob_info.open() # Returns None
reader = blobstore.BlobReader(str(blob_key))
writer = open(save_path, 'w')
writer.write(reader.read())
print blob_key, 'written to', save_path
def test_serial_pipeline(self):
stage = student_use_data_report.StudentUseDataReportSerialPipeline(
self.query_config)
stage.start_test()
self.assertIsNotNone(stage.outputs.xlsx_blob_key)
self.write_out_blob(stage.outputs.xlsx_blob_key)
答案 0 :(得分:0)
原来我只是错过了.value
属性,在这里:
self.assertIsNotNone(stage.outputs.xlsx_blob_key)
self.write_out_blob(stage.outputs.xlsx_blob_key.value) # Don't forget .value!!
<强> [UPDATE] 强>
SDK仪表板还公开blobstore中所有blob的列表,方便地按创建日期排序。它位于http://127.0.0.1:8000/blobstore
。
答案 1 :(得分:0)
如果您展示如何完成blobstore文件或者您可以单独尝试该终结代码,那么它可能会很有用。听起来,Files API没有在dev appserver上正确地完成文件。