私はGAEの使用状況で、次のアプリケーションを作成する必要があります。アップロードしたファイルを保存してGAEでそれを返す方法は?
- ユーザー(のはmyapp.appspot.com/uploadするPOSTを言わせて)いくつかのファイルをアップロードします。
- 私はそれを(データストア内に)保存してリンクを返す必要があります。
- 提供されたリンクに基づいて、ユーザーは次の5分以内にファイルをダウンロードできるはずです。
app.yamlを
application: synoext version: 1 runtime: python api_version: 1 handlers: - url: /upload script: synoext.py - url: /file/\w+ script: synoext.py - url: /cleanup script: synoext.py
synoext.py
import datetime import logging import urlparse from google.appengine.ext import webapp from google.appengine.ext.webapp.util import run_wsgi_app from google.appengine.ext import db from google.appengine.api import urlfetch class Files(db.Model): file = db.BlobProperty() added = db.DateTimeProperty(auto_now_add=True) class UploadFile(webapp.RequestHandler): def post(self): logging.info('(POST) Uploading new file') # saving file in the database file = Files() file.file = db.Blob(self.request.get("file")) file.put() self.response.out.write('http://myapp.appspot.com/' + str(file.key())) class GetFile(webapp.RequestHandler): def get(self, key): file = db.get(key) if file is not None: self.response.headers['Content-Type'] = 'application/x-bittorrent' self.response.out.write(file.file) else: self.response.set_status(404) class Cleanup(webapp.RequestHandler): def get(self): '''Automatically run job (cron) to delete old records (maximum 10000) from Files database (records, which are older than 5 minutes) ''' fiveMinutesAgoDate = datetime.datetime.now() - datetime.timedelta(minutes=5) q = db.GqlQuery("SELECT * FROM Files WHERE added < :1", fiveMinutesAgoDate) results = q.fetch(10000) db.delete(results) self.response.out.write('{"result": true}') application = webapp.WSGIApplication( [('/upload', UploadFile), ('/file/(\w+)', GetFile), ('/cleanup', Cleanup)], debug=True) def main(): run_wsgi_app(application) if __name__ == "__main__": main()
それは正しいです:
私は次のように作成しましたか?アプローチは正しいですか?または、データストアを使用しないでください。
更新。奇妙ですが、次のコード
def get(self, key):
file = db.get(key)
if file is not None:
正しくないキーを使用すると正しく動作しません。 ここで何が間違っていますか?
Cronジョブの時間制限は、他のオフラインタスクと同じ10分です.10分です。ただし、個々のタスクをETAでエンキューして各BLOBを削除することは、より良い解決策になります。 –
@ニックオハイオ州知っておいて、私は感謝を知らなかった。私はいつも、cron-jobsがユーザーに面会していると思っていました。コメントの2番目の部分に関しては、mapper-apiを使用するよりも優れていますか? – systempuntoout
Mapreduceは一括更新には適していますが、ここではどのレコードを更新する必要があるか正確に分かります。そのレコードだけを削除するレコードごとに1つのタスクをエンキューするのは簡単で、うまくいくはずです。 –