Django每次从Heroku收集静态数据都会推送到S3

Django每次从Heroku收集静态数据都会推送到S3,django,heroku,django-storage,Django,Heroku,Django Storage,我将django存储用于S3(和S3BotoStorage)的静态文件。当我从本地机器收集静态数据时,行为与预期一样,只将修改过的文件推送到S3。这个过程需要PythonDateUtils 1.5来检查修改的时间 但是,在Heroku上执行相同操作会导致推送每个文件,尽管设置是相同的。然后我查看了Heroku本身上文件的修改时间,似乎os.stat(static_filename).st_mtime与上次推送的时间相同 这是预期的行为吗?heroku是否会在git没有更改的情况下复制文件?我刚刚

我将django存储用于S3(和S3BotoStorage)的静态文件。当我从本地机器收集静态数据时,行为与预期一样,只将修改过的文件推送到S3。这个过程需要PythonDateUtils 1.5来检查修改的时间

但是,在Heroku上执行相同操作会导致推送每个文件,尽管设置是相同的。然后我查看了Heroku本身上文件的修改时间,似乎os.stat(static_filename).st_mtime与上次推送的时间相同


这是预期的行为吗?heroku是否会在git没有更改的情况下复制文件?

我刚刚遇到了完全相同的问题,并联系了heroku的支持人员以了解情况。我向他们提出的问题是

我在做一些部署时遇到了一个棘手的问题。似乎在每次推送时,所有文件上修改的日期都会更新为新的deploy/git推送发生的时间。这是故意的行为吗

考虑到Django的
collectstatic
命令在评估是否应将文件复制到静态资产的最终存储后端时仅检查文件的修改日期,这意味着在每次新推送时,首先从远程存储中删除所有文件(在本例中为S3),然后重新上载。就带宽消耗和请求而言,这是一个非常缓慢且浪费的过程

我今天从Heroku的一名支持人员“Caio”那里得到的答案是

嗨,这就是它目前的工作原理,是的。我正在将您的反馈发送给我们的运行时团队,看看我们是否可以将文件打包为原始日期


我同意这很烦人——你可以做一些事情。我覆盖collectstatic命令,并在生产设置中连接它。下面是我使用的命令:

```

或者,您可以使用Heroku在实际调用命令之前先进行试运行这一事实。如果失败,它将不会运行它,这意味着您可能会设计一个错误(例如,通过删除设置中的静态根目录),但这种方法让我感到紧张:


经Alen确认,Heroku在部署时会更改文件的修改日期。然而,AmazonS3还有一个名为etag的属性,它是文件内容的md5散列。可以使用此选项检查文件是否已更改,而不是如中所实现的修改日期


我将代码打包并修复了我发现的一些错误,并将其作为一个组件放到Github上。它包括一个新的管理命令
fasts3collectstatic
,该命令只上载新文件。查看Github页面以获取安装说明。

为什么不从本地计算机运行collectstatic

python manage.py collectstatic --noinput --settings=settings.[prod]

我强烈建议对s3的任何django静态部署使用,无论是本地部署还是从heroku服务器部署。它忽略修改过的日期,并利用md5哈希(S3API将非常快速地提供该哈希)和(可选)缓存来缩放静态部署。我的静态部署时间从大约10-15分钟缩短到<2分钟,只部署实际更改的文件

尝试将
禁用\u COLLECTSTATIC=1
设置为应用程序的环境设置-这将禁用应用程序在每次推送时运行

有关详细信息,请参阅本文-:

我发现简单地设置配置就可以了-不需要同时启用
user env compile
-这可能是因为它已经从实验室进入了生产环境

注意:部署由Heroku python构建包管理,您可以在这里看到-

编辑1


我刚刚对此做了一系列测试,可以确认
DISABLE\u COLLECTSTATIC
确实禁用了COLLECTSTATIC,而不管
user env compile
设置如何-我认为这现在在主干中(但这只是猜测)。似乎并不关心设置是什么-如果
DISABLE\u COLLECTSTATIC
作为一个配置变量存在,则使用它。

您可以通过设置一个环境变量来禁用COLLECTSTATIC命令,如果这是您想要的:另一种方法可能是让存储后端检查哈希值代替上次修改的值。S3有一个etag,它是该文件的md5,但我认为它没有文档记录。谢谢!我会试试看。
INSTALLED_APPS += ('mysite.disablecollectstatic',)
python manage.py collectstatic --noinput --settings=settings.[prod]
> Sometimes, you may not want Heroku to run collectstatic on your behalf.
> You can disable collectstatic by enabling user-env-compile as well:

$ heroku labs:enable user-env-compile
$ heroku config:set DISABLE_COLLECTSTATIC=1