【问题标题】:Asynchronous File Upload to Amazon S3 with Django使用 Django 将文件异步上传到 Amazon S3
【发布时间】:2010-10-14 19:14:22
【问题描述】:

我正在使用这个文件存储引擎在上传文件时将文件存储到 Amazon S3:

http://code.welldev.org/django-storages/wiki/Home

上传需要相当长的时间,因为文件必须先从客户端上传到 Web 服务器,然后再将 Web 服务器上传到 Amazon S3,然后才会向客户端返回响应。

我想让发送文件到 S3 的过程是异步的,这样响应可以更快地返回给用户。使用文件存储引擎执行此操作的最佳方法是什么?

感谢您的建议!

【问题讨论】:

    标签: python django amazon-s3


    【解决方案1】:

    我对这个问题采取了另一种方法。

    我的模型有 2 个文件字段,一个使用标准文件存储后端,另一个使用 s3 文件存储后端。当用户上传文件时,它会存储在本地。

    我的应用程序中有一个管理命令,它将所有本地存储的文件上传到 s3 并更新模型。

    因此,当请求文件时,我会检查模型对象是否使用 s3 存储字段,如果是,我会发送重定向到 s3 上的正确 url,如果不是,我会发送重定向,以便 nginx 可以为磁盘中的文件。

    这个管理命令当然可以由任何事件触发,比如 cronjob 或其他。

    【讨论】:

      【解决方案2】:

      可以让您的用户使用特殊表单(在隐藏字段中包含加密的策略文档)从浏览器直接将文件上传到 S3。上传完成后,它们将被重定向回您的应用程序。

      更多信息在这里:http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1434

      【讨论】:

      • 太棒了! 是直接 S3 上传的解决方案。谢谢西蒙!
      • 实际上,您无法验证上传请求和附加的任何数据。这会产生安全性不足。
      【解决方案3】:

      有一个应用程序 :-)

      https://github.com/jezdez/django-queued-storage

      它完全满足您的需求 - 甚至更多,因为您可以设置任何“本地”存储和任何“远程”存储。此应用会将您的文件存储在快速“本地”存储(例如 MogileFS 存储)中,然后使用 Celery (django-celery) 尝试异步上传到“远程”存储。

      几点说明:

      1. 棘手的是 - 您可以将其设置为复制和上传,或上传和删除策略,一旦上传就会删除本地文件。

      2. 第二个棘手的事情 - 它会从“本地”存储中提供文件,直到它没有被上传。

      3. 它还可以配置为上传失败时重试的次数。

      安装和使用也非常简单明了:

      pip install django-queued-storage
      

      附加到INSTALLED_APPS:

      INSTALLED_APPS += ('queued_storage',)
      

      models.py:

      from queued_storage.backends import QueuedStorage
      queued_s3storage = QueuedStorage(
          'django.core.files.storage.FileSystemStorage',
          'storages.backends.s3boto.S3BotoStorage', task='queued_storage.tasks.TransferAndDelete')
      
      class MyModel(models.Model):
          my_file = models.FileField(upload_to='files', storage=queued_s3storage)
      

      【讨论】:

      • 我如何强制它替换原始文件我尝试重新上传一个新文件?现在它正在创建 name_1、name_2 等
      【解决方案4】:

      你可以解耦这个过程:

      • 用户选择要上传的文件并将其发送到您的服务器。在此之后,他看到一个页面“感谢您上传 foofile.txt,它现在存储在我们的存储后端”
      • 当用户上传文件时,它会存储在您服务器上的临时目录中,如果需要,一些元数据会存储在您的数据库中。
      • 服务器上的后台进程然后将文件上传到 S3。这只有在您拥有对服务器的完全访问权限的情况下才有可能,这样您就可以为此创建某种“守护程序”(或简单地使用 cronjob)。*
      • 显示的页面异步轮询并向用户显示某种进度条(或简单的“请稍候”消息。仅当用户应该能够“使用”时才需要此消息(将其放在消息,或类似的东西)上传后直接。

      [*:如果您只有一个共享主机,您可以构建一些解决方案,在用户浏览器中使用隐藏的 iframe 来启动脚本,然后将文件上传到 S3]

      【讨论】:

        【解决方案5】:

        您可以直接将媒体上传到 s3 服务器,而无需使用 Web 应用程序服务器。

        请参阅以下参考资料:

        亚马逊 API 参考:http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?UsingHTTPPOST.html

        一个 django 实现:https://github.com/sbc/django-uploadify-s3

        【讨论】:

          【解决方案6】:

          由于这里的一些答案建议直接上传到 S3,这里有一个使用 plupload 的 Django S3 Mixin: https://github.com/burgalon/plupload-s3mixin

          【讨论】:

            【解决方案7】:

            我在上传图片时遇到了同样的问题。您不能将文件传递给 Celery 工作人员,因为 Celery 需要能够腌制任务的参数。我的解决方案是将图像数据解构为一个字符串并从文件中获取所有其他信息,将这些数据和信息传递给我重建图像的任务。之后您可以保存它,它将发送到您的存储后端(例如 S3)。如果要将图像与模型相关联,只需将实例的 id 传递给任务并在那里检索它,将图像绑定到实例并保存实例。

            当文件通过表单上传时,它在您的视图中作为 UploadedFile 文件类对象可用。您可以直接从 request.FILES 中获取它,或者最好先将其绑定到您的表单,运行 is_valid 并从 form.cleaned_data 检索类似文件的对象。在这一点上,至少你知道它是你想要的那种文件。之后,您可以使用 read() 获取数据,并使用其他方法/属性获取其他信息。见https://docs.djangoproject.com/en/1.4/topics/http/file-uploads/

            我实际上最终编写并分发了一个小包来异步保存图像。看看https://github.com/gterzian/django_async 是的,它只是用于图像,您可以分叉它并根据您的情况添加功能。我将它与https://github.com/duointeractive/django-athumb 和 S3 一起使用

            【讨论】:

              猜你喜欢
              • 2016-11-22
              • 2015-03-17
              • 2021-08-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-08-17
              • 1970-01-01
              相关资源
              最近更新 更多