Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Heroku要在新部署中安装旧的Python(pip)依赖项?_Python_Django_Heroku - Fatal编程技术网

为什么Heroku要在新部署中安装旧的Python(pip)依赖项?

为什么Heroku要在新部署中安装旧的Python(pip)依赖项?,python,django,heroku,Python,Django,Heroku,(在Heroku自己的支持下询问) 我们刚刚在一个项目中发现了一个依赖性问题,开发环境之间的库不匹配。细节不相关,但根本原因是依赖项在其setup.py中有一个“>=”版本匹配-这意味着当开发人员重建其环境时,他突然得到了最新版本(0.4.0),而不是以前的旧版本(0.3.11),并开始得到弃用警告 作为调试过程的一部分,我的印象是,无论何时将repo推送到Heroku,都会重建一个干净的环境,这让我错误地认为,我们的开发环境(每天重建)都会安装最新版本。因为我们在开发环境中没有看到这个问题,所

(在Heroku自己的支持下询问)

我们刚刚在一个项目中发现了一个依赖性问题,开发环境之间的库不匹配。细节不相关,但根本原因是依赖项在其
setup.py
中有一个“>=”版本匹配-这意味着当开发人员重建其环境时,他突然得到了最新版本(0.4.0),而不是以前的旧版本(0.3.11),并开始得到
弃用警告

作为调试过程的一部分,我的印象是,无论何时将repo推送到Heroku,都会重建一个干净的环境,这让我错误地认为,我们的开发环境(每天重建)都会安装最新版本。因为我们在开发环境中没有看到这个问题,所以我决定进行调查,并在远程环境中运行了
heroku-run-pip-list

我(非常)惊讶地看到,这是一个旧的和过期的依赖关系的幸运下降,根本不是一个干净的环境。事实证明,作为旧安装的一部分,我们可能有一个问题,那就是我们在现场环境中愉快地调试生活

解释这一点最简单的方法是BeautifulSoup库。我们最近从v3更新到v4,作为其中的一部分,库本身将PyPI上的名称从
BeautifulSoup
更改为
beautifulsoup4
。我们更新了
requirements.txt
以反映这一点,但如果现在在Heroku环境中运行
pip list
,我会得到以下两个结果:

~ $ heroku run bash
~ $ pip list
BeautifulSoup (3.2.1)
beautifulsoup4 (4.3.2)
所以,旧的依赖还没有被清除,它只是坐在那里。通过启动python会话,我可以很容易地证明这一点:

~ $ python
Python 2.7.4 (default, Apr  6 2013, 22:14:13)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import bs4
>>> import BeautifulSoup
>>>
这有点令人震惊,我很惊讶这并没有在某个时候扼杀我们的应用程序

所以,问题是——Heroku如何在幕后管理依赖关系——它显然不会清除python环境,并在每次部署时重新运行
pip install
——我有什么办法可以强制这种行为吗

[编辑1]

FWIW,这是进行安装的构建包-

[编辑2]

从文档中:

CACHE_DIR的内容将在构建之间持久化。您可以在此处缓存长过程(如依赖项解析)的结果,以加快将来的构建

以及:

bin/compile脚本将获得一个CACHE_DIR作为其第二个参数,该参数可用于存储构建之间的工件。在后续构建期间,存储在该目录中的工件将在CACHE_DIR中可用。CACHE_DIR仅在slug编译期间可用,并且特定于正在构建的应用程序

建议是:

Heroku用户可以使用Heroku repo插件清除他们用于应用程序的构建包创建的构建缓存


也就是说,虽然我知道缓存用于加快未来的编译速度,但我不明白为什么缓存中的所有内容都要安装。这没有任何意义?

Heroku在
/app/.Heroku/Python
中安装您的Python环境,整个
.Heroku
目录在每个构建开始时从CACHE\u DIR复制,然后在结束时返回CACHE\u DIR。(如果在buildpack脚本中搜索
restore\u cache
dump\u cache
,您将看到执行此操作的行。)

因此,一旦你在Heroku应用程序中安装了一些东西,它就会一直存在,除非缓存目录以某种方式被删除。显然,这并不理想,但这样做是为了避免由于在每个部署上重新编译和安装所有依赖项而导致的非常长的构建时间。(值得一提的是,我认为现在有一种更好的方法可以实现这一点,即使用wheels缓存已编译的包,这样您每次都可以获得一个全新的环境,而无需等待所有内容都重建。我可能会尝试举一个例子,向Kenneth Reitz说明这一点。)

从短期来看,您似乎可以从显式固定所有依赖项的版本(包括依赖项的依赖项等)中获益。简单地运行
pipfreeze>requirements.txt将是一个良好的开端,尽管您可能还想了解一下。您确实希望避免您刚才描述的那种情况,即开发人员从
requirements.txt
重建其环境,最终得到不同版本的软件包


至于BeautifulSoup更改其包名(但可能不是您导入的模块名),这听起来真的很可怕,这正是Heroku缓存崩溃的那种情况!我认为唯一的解决办法是使用heroku repo插件并完全关闭缓存。

感谢您的全面回答。我们确实使用完全固定运行了很长一段时间,但后来发现依赖项的依赖项与固定版本之间不匹配。使用
heroko_repo
purge_cache
至少可以清除环境,让我们了解到底发生了什么。这和内务管理一样重要——将我们不再依赖的旧DEP从环境中清除。PS如果你在向KR询问BuildPack,这一次也让我们绊倒了(作为调试的一部分)-