Django:哪种方法更好 [virtualenv + pip] 还是 [手动在svn中携带包]?
我有一个django项目,里面用到了很多第三方应用,所以我想在两种方法中选择一种来管理我的情况:
- 我可以使用[ virtualenv + pip ],并通过
pip freeze
生成一个需求文件来管理我的项目依赖。
这样我就不用担心这些应用了,但我不能把它们和我的代码一起提交到svn。
我可以在svn结构中创建一个lib文件夹,把我的应用放在那里,然后把这个文件夹添加到 这样,我的依赖就可以提交到svn,但我需要自己管理sys.path
中。sys.path
。
我应该选择哪种方式呢?
这两种方法各自的优缺点是什么?
更新:
方法1的缺点:在使用appengine时比较困难。
3 个回答
Virtualenv 和 pip 在一台机器上处理多个 Django 项目时非常好用。不过,如果你只有一个项目在编辑,那就没必要使用 virtualenv 了。
这是我目前使用的方式。
所有项目在根目录下都会有一个虚拟环境目录,我们把它命名为 .env,并在版本控制系统中忽略它。开发者开始开发的第一件事就是初始化这个虚拟环境,并安装在 requirements.txt 文件中指定的所有依赖。我更喜欢把虚拟环境放在项目目录里,这样开发者一眼就能看到,而不是放在其他地方,比如 $HOME/.virtualenv
,然后再通过 source $HOME/virtualenv/project_name/bin/activate
来激活环境。这样,开发者可以直接从项目根目录调用虚拟环境的可执行文件,操作起来更方便,比如:
.env/bin/python
.env/bin/python manage.py runserver
在部署时,我们有一个 fabric 脚本,首先会把我们的项目目录和 .env 目录打包成一个 tarball,然后把这个 tarball 复制到线上服务器,解压到部署目录,并进行一些其他操作,比如重启服务器等。当我们在线上服务器上解压 tarball 时,fabric 脚本会确保再次运行虚拟环境,这样 .env/bin
中的路径就会被修正。这意味着我们在线上服务器上不需要重新安装依赖。fabric 的部署流程大致如下:
fab create_release:1.1 # create release-1.1.tar.gz
fab deploy:1.1 # copy release-1.1.tar.gz to live server and do the deployment tasks
fab deploy:1.1,reset_env=1 # same as above but recreate virtualenv and re-install all dependencies
fab deploy:1.1,update_pkg=1 # only reinstall deps but do not destroy previous virtualenv like above
我们也不通过 setup.py 将项目源代码安装到虚拟环境中,而是将其路径添加到 sys.path 中。因此,在使用 mod_wsgi 部署时,我们需要在 vhost 配置中指定两个路径,类似于:
WSGIDaemonProcess project1 user=joe group=joe processes=1 threads=25 python-path=/path/to/project1/.env/lib/python2.6/site-packages:/path/to/project1/src
简而言之:
- 我们仍然使用 pip 和虚拟环境来管理依赖。
- 在部署时不需要重新安装依赖。
- 我们需要稍微维护一下 sys.path 的路径。
这个问题到现在为止还没有人回答(至少对我来说是这样)。最近对此有一些讨论:
https://plus.google.com/u/0/104537541227697934010/posts/a4kJ9e1UUqE
Ian Bicking在评论中提到:
我认为我们可以做一些结合这两种系统的事情。我之前发过一个处理这个问题的方案(我想我应该整理一下再发一次)。在Python中,你可以用非常类似的方式来处理库,同时仍然使用我们现有的工具来管理这些库。你可以这样做,但其实并不明显怎么做,所以人们往往依赖于在部署时重新安装包。
http://tarekziade.wordpress.com/2012/02/10/defining-a-wsgi-app-deployment-standard/
第一种方法似乎是Python开发者中最常见的。当我第一次开始用Django开发时,感觉有点奇怪,因为在做PHP时,通常会把第三方库放进项目的代码库里。但正如Ian Bicking在链接的帖子中所说,PHP的部署方式忽略了一些像不可移植的库这样的东西。你不想把像mysqldb或PIL这样的东西打包到你的项目里,这些更适合用像Pip或distribute这样的工具来处理。