GAE Python - 每天将CSV保存到同一Blobstore元素

1 投票
2 回答
510 浏览
提问于 2025-04-17 20:03

我在看一些类似的问题,但没找到可以直接用的答案。我正在使用Google App Engine,想用unicodecsv做一个简单的CSV导出,这个功能运行得很好。这个导出是每天都要运行一次,并且每次都保存为同一个Blobstore项目,这样就可以通过同一个网址来获取结果。

我知道这不是Blobstore项目最初的设计目的,但我也看到一些文章说他们成功实现了这个功能。不幸的是,由于我不是很有经验的程序员,没办法把那些方法应用到我的情况中。如果有人能给我一些建议,告诉我怎么实现这个功能,那就太好了。

class ShopExport(webapp2.RequestHandler):
  def get(self):
    shops = Shop.all()
    self.response.headers[str('Content-Type')] = str('application/csv')
    self.response.headers[str('Content-Disposition')] = str('attachment; filename="shops.csv"')
    writer = unicodecsv.writer(self.response.out, encoding='utf-8')
    writer.writerow(["id", "name", "domain", "category", "deeplink"])
    for shop in shops:
      writer.writerow(["'"+shop.keyname+"'", "'"+shop.name+"'", "'"+shop.url+"'", "'"+shop.category+"'", "'"+shop.url_aff+"'"])

2 个回答

1

你不能直接覆盖一个blob存储里的内容,只能把它删除。你对blob存储的键没有控制权,所以你需要在你的应用里管理好这个链接,并把它指向当前的blob存储地址。至于如何往blob存储里写东西,可以看看文件API的相关内容。

https://developers.google.com/appengine/docs/python/blobstore/overview#Writing_Files_to_the_Blobstore

4

正如Tim所说,你不能直接覆盖blobstore中的实体,但你可以每次创建一个新的实体,并记住它的键,以便使用这个新的实体:

class BlobKey(db.Model) :
    blob_key = db.StringProperty()

然后,在一个定时任务处理器中,你可以:

blob_key = BlobKey.all().get()
blob = blobstore.get(blob_key)
if blob : blob.delete()
db.delete( blob_key )    # you don't need it anymore

file_name = files.blobstore.create( mime_type = 'text/csv')
with files.open(file_name, 'a') as f:
    f.write( your_content )

files.finalize(file_name)
blob_key = files.blobstore.get_blob_key(file_name)

BlobKey( blob_key = str(blob_key) ).put()   # save the new key

最后,当你提供你的文件时(在一个 BlobstoreDownloadHandler 中),你只需要这样做:

blob_key = BlobKey.all().get()
if blobstore.get(blob_key):
    self.send_blob(blobstore.BlobInfo.get(blob_key),
        content_type = 'text/csv', save_as=True)    # False to mangle file name
else:
    self.error(404)

撰写回答