使用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
然后heroku local:run which python
返回:
/usr/local/bin/python
which python
返回:
/Users/myusername/MyProject/venv/bin/python #the correct value
heroku local:run
使用当前安装的虚拟环境?答案 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.start
和see here(注意forego
在Go中使用Foreman - child_process.spawn()
)。这些又调用Node.js run.go
来生成forego
进程,再次分别使用run
或start
作为参数。
在此之后 - 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。