目前,我在一家大公司工作,我们需要将python2的旧的Django大项目转换为python3版本,因此我进行了大量研究,但仍然找不到最适合转换哪个版本的Python和Django的完美答案。
目前,我使用的是旧版本的Python:2.7.16和Django:1.9.13。
任何人都可以为上述python2到python3的旧版本推荐最适合我的Python和Django版本。
目前,我在一家大公司工作,我们需要将python2的旧的Django大项目转换为python3版本,因此我进行了大量研究,但仍然找不到最适合转换哪个版本的Python和Django的完美答案。
目前,我使用的是旧版本的Python:2.7.16和Django:1.9.13。
任何人都可以为上述python2到python3的旧版本推荐最适合我的Python和Django版本。
Answers:
我以为我会在Wim的答案所倡导的策略中添加一些内容-首先在2.7和3.x上获得合适版本的Django-并概述一些对我有用的策略。
我在这里的标准是Django迁移可以相当广泛地参与(实际上需要比2 => 3工作更多的思考)。因此,我将移动到最新和最好的1.11,以便您已经为2.7用户提供了一些价值。1.11上可能有大量的2.x之前版本的兼容垫片,并且您将收到其2.x弃用警告。
最好考虑所有方面,例如第三方库的可用性,CI / devops套件的支持以及所选服务器OS映像的可用性。例如,您始终可以安装3.8并尝试通过pip安装您的requirements.txt。
requirement.txt
文件,但是...pip install -e <your directory>
。这意味着,您可以在2个不同的终端中针对相同的单元测试运行2.7和3.x。是的,如果您允许的话,它将破坏2.7代码和Django。所以...
以预览模式或针对单个文件运行。看到它坏了,也看到它做对了。
将其限制为仅执行不超过2.7或Django的某些转换。 print x
=> print (x)
并且except(Exception) as e
是2个不用理会的人。
这是我的受限制的命令:
2to3 $tgt -w -f except -f raise -f next -f funcattrs -f print
好处是,随着您对应用程序特定问题的了解越来越多,您可以构建一套可以在1个文件或多个文件上运行的更改,并完成大多数工作而不会破坏2.7或Django。在经过适当节流的2to3通行证后应用此方法。这就使您在编辑器中残留了清理工作,并使测试通过。
black是一种代码格式化程序,它使用Python 3 AST进行分析。它不会尝试运行代码,但是会标记语法错误,以防止其进入AST阶段。但是,您将必须做一些点子安装全局魔术才能到达那里,并且您必须认可black的有用性。
听#155转向Python 3的实际步骤应该为您提供一些工作思路。查看它的显示链接。他们喜欢谈论Instagram(?)的举动,该举动涉及在公共代码库和同一git分支上逐步将运行2.7代码转换为3.x语法,直到触发一天。
另请参见The Conservative Python 3移植指南
您使用Django 1.11 EOL(2020年4月)的时间非常短,因此如果您有2个以上的开发资源可以投入使用,我将考虑并行执行以下操作:
DEV#1:使用2.7,从Django 1.11颠簸开始(理论上认为Django 1.11可能是到达Django 2.x的最佳起点)。
DEV#2:开始使用非Django实用程序代码的Python 3.6 / 3.7。由于此时代码是2.7兼容的,因此您可以将其合并到#1中。
查看这两个任务的进行方式,评估与Django相关的项目的风险以及Python 3的痛苦。您已经缺少Python 2.7 EOL了,但是过时的Web框架可能比旧版Python 2.7更危险,至少持续了几个月。因此,我不会等太久就开始从Django 1.9进行迁移,这样做不会浪费您的工作。当您看到进度时,您将开始更好地看到项目风险。
您最初的2to3进度会很慢,但是工具和指南足够好,您会很快加快速度,因此在开始积累经验之前,请不要过分考虑。Django方面取决于您对框架中重大变更的了解,这就是为什么我认为最好尽早开始的原因。
这并不是因为我不信任它-对于第三方库来说,这是很了不起的-而是我不想添加复杂的永久依赖项(而且我懒得阅读它的文档)。我已经用3.x兼容语法编写2.7代码很长时间了,所以我真的没有必要使用它们。 如果工作很艰巨,您的里程可能会有所不同,不要走这条路。
相反,我使用这种类型的内容创建了py223.py(57 LOC包括注释),其中大部分与标准库中弃用和名称更改的解决方法有关。
try:
basestring_ = basestring
except (NameError,) as e:
basestring_ = str
try:
cmp_ = cmp
except (NameError,) as e:
# from http://portingguide.readthedocs.io/en/latest/comparisons.html
def cmp_(x, y):
"""
Replacement for built-in function cmp that was removed in Python 3
"""
return (x > y) - (x < y)
然后从py223导入以解决这些特定问题。稍后,我将放弃导入内容并将那些奇怪的内容移至其他位置isinstance(x, basestr_)
,isinstance(x, str)
但我事先知道没有什么可担心的。
six
用于兼容性层,因此,如果您想在过渡期间在Django项目中使用它,那么这并不是“添加复杂的永久依赖项”。
pip install -e ...
(用小写字母-e
),对吗?
我的建议是先升级到Django==1.11.26
,这是同时支持Python 2和Python 3的Django的最新版本。暂时保留当前版本的Python 2.7。
仔细阅读1.10.x和1.11.x的发行说明,检查是否已弃用并修复从1.9.x代码停止工作的所有内容。事情会破裂。Django发展迅速。对于大型Django项目,可能需要进行许多代码更改,并且如果您使用大量的第三方插件或库,则可能不得不考虑其版本。您的某些第三方依赖项可能已被完全放弃,因此您必须查找替换项或删除功能。
要查找每个版本升级的发行说明,只需谷歌“ Django的新功能”。这些匹配将精心记录所有弃用和更改:
一旦webapp在Django 1.11上运行正常,并且所有测试都通过了( 确实有一个测试套件,对吗?),则可以进行Python 3转换,同时保持Django版本不变。Django 1.11最多支持Python 3.7,因此这将是一个不错的目标版本。到处都是unicode,因为字节和文本之间的隐式转换现在已经不复存在,并且许多Python 2 webapp都依赖于此。
一旦该项目在Django 1.11和Python 3.7上运行良好,然后您就可以考虑升级到Django 3.0,遵循与之前相同的过程-阅读发行说明,进行必要的更改,运行测试套件并签出开发服务器中的webapp手动。
pip install -E
。单元测试运行后,开始使用Django-on-3x进行测试,并再次使代码在2和3中正常工作。在进行一些仔细的编码后,请注意不要烧掉2.7网桥-例如,没有f字符串-切换将是非常滑稽。一旦3.x完全稳定,请开始使用仅3.x代码。优点是生产2.7始终处于切换状态,直到切换为止。
我会先升级到py3。您需要setup.py
在stable / 1.9.x分支(https://github.com/django/django/blob/stable/1.9.x/setup.py)上的Django存储库中查看py3支持的版本为3.4(停用)和3.5。
使用py3.5和Django 1.9后,您可以一次升级一个,直到获得要结束的版本。例如Django 1.11支持py3.5和py3.7,因此
py27/dj19 -> py35/dj19 -> py35/dj1.11 -> py37/dj1.11 ... -> py37/dj2.2
dj2.2是第一个支持py3.8的版本,但是如果您在通常保守的环境中工作,我可能会停止在py37 / dj2.2。
如果您还有其他软件包,则需要找到可以在每个步骤中一起使用的版本组合。制定计划是关键,一次只升级一个组件通常可以节省您的时间。
未来的库(https://python-future.org/)将在许多棘手的情况下为您提供帮助,同时您需要在py27和3.x上都运行代码。六个也很棒。我会避免滚动自己的兼容性层(为什么要重新发明轮子?)
如果有可能,请在开始之前尝试使单元测试覆盖率达到75-85%,并且一定要在每个升级步骤的“ from”和“ to”版本上都设置自动测试。在升级到下一个版本之前,请确保已阅读并修复了来自Django的所有警告-Django不太关心向后兼容性,因此,我通常建议在升级路径上点击每个次要版本(或至少确保您阅读了“向后”不兼容”和每个次要版本的弃用列表)。
祝您好运(我们正在从py27 / dj1.7升级300 + Kloc代码库,所以我感到您很痛苦;-)
您应该尝试拍摄当前版本。Python 3.8和Django3.0。Six库将有助于一些常规更改。无论哪种方式,您都必须进行一些重构,以便您最好使其成为最新的。