pipenv install too slow

365 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

注: 本人自19年下旬已转投poetry阵营,详见:juejin.cn/post/709238…

以下为18年首发的原文内容:

首先,已经换好源了:(如何用一行命令来换源请看:blog.csdn.net/jaket521999…

$ head -2 Pipfile
[[source]]
url = "https://mirrors.aliyun.com/pypi/simple"

换好源之后,pipenv安装还是有点慢,看了一下,发现主要是lock这一步耗时较长。

解决方案如下:

一、

安装时用:pipenv install --skip-lock python-package, 等到要部署或git push时再运行pipenv lock生成Pipfile.lock文件,例如

pipenv install --skip-lock django
pipenv lock

试了一下这个方法,安装明显快多,而且pipenv lock可以另开一个terminal来运行,整个过程就舒畅多了。

二、

在方法一的基础上,写一个脚本,install --skip-lock之后,自动在后台运行lock。


基于以上想法写了脚本增加速度:install时加上--skip-lock,然后开多一个进程在后台运行pipenv lock

系统是ubuntu18,vagrant下的config.vm.box = "ubuntu/bionic64"

结果:

$ time pipenv install django requests djangorestframework

real 0m26.462s user 0m13.008s

sys 0m2.001s

$ time pii django requests djangorestframework

real 0m18.055s user 0m5.469s

sys 0m1.132s

结论:提速了约30%,不过还是有点慢,静待kennethreitz继续给力。

代码如下:

cat ~/.bash_aliases
...
alias pii="~/.pipenv_install_while_lock_at_another_process.py"
...
cat ~/.pipenv_install_while_lock_at_another_process.py
#!/usr/bin/env python3.6
import os
import sys
from multiprocessing import Process
 
 
def subcmd(cmd):
    with os.popen(cmd) as f:
        f.read()
 
 
def main():
    os.system(f'pipenv install --skip-lock {" ".join(sys.argv[1:])}')
    cmd = "pipenv lock 2>&1 >/dev/null"   # 2>&1 >/dev/null 使得pipenv lock为静默运行
    p = Process(target=subcmd, args=(cmd,), daemon=True)  # 启动后台进程来运行命令
    p.start()
 
 
if __name__ == "__main__":
    main()

由于pipenv lock 2>&1 >/dev/null为静默运行,结果不会通知当前终端,所以过一段时间后,如果发现Pipenv.lock 未生成或者未更新,还需再手动运行pipenv lock

后记@2020-05-15

使用pipenv已经超过两年了, 这期间虽然遇到过种种问题, 但已经回不去venv+pip+requirements.txt的方案了, 因为经常会有需要在项目里新增库的情况, requirements管理起来太麻烦了; 而据说还不错的python-poetry又由于墙的原因,不便使用; 所以一直用的还是pipenv

现在的用法是

  1. 通过pip install pipenv-cn安装github上的较新版

  2. 安装库时先pip install xxx; 再执行pipenv install --skip-lock xxx; 然后另开一个终端跑pipenv lock (不用看着, 继续干其他活, 回头有空再看看lock结果就好)

  3. 在~/.bash_aliases文件里自定义alias ve="pipenv shell", 然后每次要激活虚拟环境时, 只需输入ve回车即可

  4. 运行pipenv lock时, 有坑; 它有时候会把已经安装的包全部升级到最新版, 所以一些不宜升级到最新版的要指定最大版本号, 如:

tortoise-orm = "<0.16.3" 5. 很少用到pipenv uninstall xxx, 基本都是手动去删除Pipfile里面的某一行, 然后后台运行pipenv lock

最后晒一下当前项目的Pipfile:

[[source]]
name = "aliyun"
url = "https://mirrors.aliyun.com/pypi/simple"
verify_ssl = true
 
[dev-packages]
ipython = "*"
coverage = {extras = ["toml"],version = "*"}
pytest = "*"
bandit = "*"
pytest-sanic = "*"
pytest-asyncio = "*"
fabric = "*"
 
[packages]
arq = "*"
xlrd = "*"
click = "*"
motor = "*"
django = "*"
pandas = "*"
umongo = "*"
pyyaml = "*"
aiohttp = "*"
asyncpg = "*"
ciso8601 = "*"
colorama = "*"
werkzeug = "*"
aioredis = "*"
sanic-jwt = "*"
xmltodict = "*"
xlsxwriter = "*"
asyncblink = "*"
sanic-sentry = "*"
tortoise-orm = "<0.16.3"
aiotask-context = "*"
psycopg2-binary = "*"
celery = {extras = ["msgpack", "pyamqp", "redis"],version = "*"}
beiming = {editable = true,git = "ssh://git@e.coding.net/esoaru/beiming.git"}
docx-mailmerge = "*"
gunicorn = "*"
 
[requires]
python_version = "3.8"