为什么heroku local:run想要使用全局python安装而不是当前激活的虚拟环境?

时间:2015-12-04 10:35:32

标签: python heroku virtualenv pythonpath

使用Heroku来部署我们的Django应用程序,除heroku local:run命令外,一切似乎都符合规范。

我们经常需要通过Django的manage.py文件运行命令。在远程上运行它们,作为一次性dynos,可以完美运行。 要运行本地,我们会尝试:

heroku local:run python manage.py the_command

尽管当前虚拟环境包含Django安装,但

仍然失败了
 ImportError: No module named django.core.management

通过python路径进行诊断

然后heroku local:run which python返回:

 /usr/local/bin/python

which python返回:

 /Users/myusername/MyProject/venv/bin/python #the correct value
  • 这是Heroku本地的一个错误:运行?或者我们是否错过了解其预期的行为?
  • 更重要的是:有没有办法让heroku local:run使用当前安装的虚拟环境?

3 个答案:

答案 0 :(得分:10)

在联系Heroku的支持后,我们理解了这个问题。

支持人员确认heroku local:run应按预期使用当前活动的虚拟环境

问题是本地配置问题,由于我们的.bashrc内容:heroku local:run来源.bashrc(在我们的例子中,这是在$ PATH前面加上全局Python的路径安装,在虚拟环境之前找到它。另一方面,heroku local不会提供此文件。引用他们支持的最后一条消息:

  

heroku local:run在交互模式下使用bash运行命令,该模式读取你的配置文件,vs heroku local(别名为heroku local:start),它不以交互模式运行。

答案 1 :(得分:2)

添加到Ad N的答案。它绝对坚持使用系统Python而不是使用它的虚拟环境的原因如下。

Heroku local:运行源.bashrc,其中包含用户的PATH以及对默认PATH的任何添加。这包括系统Python的位置,但不一定是任何其他Python解释器。它将使用首先找到的Python解释器,它应该是系统Python(否则非常重要的东西,如init和包管理不能正常工作,或者根本没有)

解决这个问题的方法不是将其作为heroku本地运行:运行哪个源.bashrc并包含系统Python将其作为heroku本地运行,以便它使用虚拟环境中的任何活动。

答案 2 :(得分:1)

在本地运行Heroku记录here,但它只讨论使用heroku local,文档指定的是heroku local:start的同义词

  

heroku local是heroku local的一个较短的替代品:start,它做同样的事情。

OP's self-answer指定Heroku开发人员已确认如果使用heroku local(相当于heroku local:start),则不会获取本地.bashrc和virtualenv python按预期使用

如果使用了heroku local:run,那么本地机器的.bashrc来源,OP的情况下 .bashrc前置系统python$PATH的路径,因此使用了python的系统安装。

所以,结论是heroku local:run应该使用virtualenv python,但如果.bashrc碰巧包含使其使用系统版本的命令,则将不会 python(例如,通过在路径变量中首先将路径放到系统python中)。

通过代码行走的细节

要查看代码并从该角度了解详细信息,请查看Github repository for heroku-local,尤其是commands下的forego.run。在这里,我们看到run命令有一个Javascript文件,start命令有另一个Javascript文件。看看里面,你看他们看起来非常相似,除了他们分别拨打forego.startsee here(注意forego在Go中使用Foreman - child_process.spawn())。这些又调用Node.js run.go来生成forego进程,再次分别使用runstart作为参数。

在此之后 - NewProcess定义unix.go here,在其上调用ShellInvocationCommand,这是特定于平台的。最后 - 我们在start.go中看到了问题的根源,您可以在ShellInvocationCommand中看到该个人资料来自profile。使用{{3}}时,启动过程的方法完全不同,ParameterExpression e = Expression.Parameter(typeof(IData), "e"); PropertyInfo propertyInfo = typeof(IData).GetProperty("Property"); MemberExpression m = Expression.MakeMemberAccess(e, propertyInfo); var toString = typeof (Object).GetMethod("ToString"); ConstantExpression c = Expression.Constant(data, typeof(string)); MethodInfo mi = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }); var toStringValue = Expression.Call(m, toString); Expression call = Expression.Call(toStringValue, mi, c); Expression<Func<IData, bool>> lambda = Expression.Lambda<Func<IData, bool>>(call, e); 未获取,因此使用了virtualenv python。

相关问题