Python2からPython3へのコード変換の場合、PythonとDjangoのどのバージョンが最適ですか?


11

現在私は大企業で働いており、python2の古い大きなDjangoプロジェクトをpython3バージョンに変換する必要があるため、関連する多くの調査を行いましたが、変換に最適なPythonとDjangoのバージョンに関連する完全な答えはまだ見つかりません。

現在、旧バージョンではPython:2.7.16とDjango:1.9.13を使用しています。

誰でも私の古いバージョンのpython2からpython3への変換に最適なバージョンのPythonとDjangoを私に提案できます。


python3の現在のバージョンはPython 3.8であり、Djangoの最新バージョンはDjango 3.0です。DjangoのWebサイトでは、最新バージョンのpython 3である3.8を推奨しています。pythonとdjangoの両方を最新バージョンに高速化したくない特別な理由はありますか?
Green Cloak Guy

2
事例として、数日前に私が数年維持してきたDjangoベースのWebサイトが、python2.7を使用してホストされているサーバーで実際に実行されているのに気づいたのですが、python3を使用してローカルで実行しています。 7。私が見つけた唯一の違いは、初めてどこかでf-stringsを使用しようとしたときにWebサーバーのバージョンがクラッシュしたことです。それ以外の場合は、テストと機能の追加を目的として、ローカルとリモートで期待どおり(まったく同じ)実行されています。私の完全に事例的な結論は、Djangoは一般にほとんどのものと互換性があるということです。
Green Cloak Guy

1
最新バージョンの場合、一部の人はお勧めしません。最新バージョンでは、新しい更新に関連する問題がある場合、解決策を見つけるのが難しい場合があるため、現在のプロジェクトでは、このような種類のリスクをかけたくないためです。テスト目的で、私は自分のプロジェクトを最新のdjangoを含むpython 3.7.3最新バージョンに変換し始め、すでに30種類の問題を発見しました。

それは注意されるべきです-この質問は私のためのレビュー監査で思い付きました。「ドキュメントや参照はありますか」は、明らかにオフトピックです(オフサイトのリソースを求めています)。ただし、質問を編集して、以下の承認された回答に導くことができると思います。
theMayer、

回答:


3

Wimの答えが提唱する戦略に少し追加したいと思いました。まず、適切なバージョンのDjangoを2.7と3.xの両方で動作させてください-そして、私のために働いたいくつかの戦術を概説します。

Python 2.7は、3.xでトリガーを引くまで、エスケープポッドです。

  • テストは両方で実行する必要があります
  • f-stringsなどの3.x固有の機能を使用しない
  • 最初にPython 3.x、次に2.7で動作しない後のDjango 2.xのみ
  • 早めに始め、分析しすぎないで、ビッグバンアプローチを避けます
    • 最初はファイルごと。
    • ユーティリティスイートのように、テストスイートがある最低レベルのコードから始めます。
    • 可能であれば、2.7の本番ブランチへの変更を徐々にマージし、3.xの移植コードを製品の変更で最新の状態に保つようにしてください。

Djangoのどのマイナーバージョンから始めますか?

ここでの私の基準は、Djangoの移行がかなり関与する可能性があることです(実際には、2 => 3の作業よりも多くの思考が必要です)。ですから、2.7のユーザーに何らかの価値を既に提供している方法で、最新かつ最高の1.11に移動します。そこ1.11の前2.xの互換性シムのかなりの数は、おそらくだ、あなたはその2.xの非推奨の警告を取得することがあります。

どのマイナーバージョンのPython 3.xから始めますか?

サードパーティのライブラリの可用性、CI / devopsスイートからのサポート、選択したサーバーOSイメージでの可用性など、あらゆる角度を考慮するのが最善です。たとえば、常に3.8をインストールして、requirements.txtを単独でpipインストールすることもできます。

レバレッジgitの(またはものは何でも使うSCM)とvirtualenvの

  • 別のrequirement.txtファイルですが...
  • あなたはファイルベース、gitのレポを持っている場合、あなたはで各venvを指すことができます同じコードラインを持ちますpip install -e <your directory>。つまり、2つの異なる端末で、同じユニットテストに対して2.7と3.xを実行できます。
  • 異なるポートで2.7と3.xのDjangoサーバーを並べて実行し、FirefoxとChromeを指すようにすることもできます。
  • 頻繁に(少なくとも移植ブランチで)コミットし、git bisectについて学びます。

2to3を利用する

はい、可能であれば2.7コードとDjangoが壊れます。そう...

  • プレビューモードまたは単一のファイルに対して実行します。何が壊れているかを確認するだけでなく、何が正しく行われたかも確認してください。

  • 2.7やDjangoを壊さない特定の変換のみに絞ってくださいprint x=> print (x)except(Exception) as e2つの簡単な方法です。

これは私のスロットルされたコマンドがどのように見えるかです:

2to3 $tgt -w -f except -f raise -f next -f funcattrs -f print
  • 本当に自信があるまで、ファイルごとに実行してください。

一括変換には、エディタではなくsedまたはawkを使用してください。

利点は、アプリの特定の懸念に気づくにつれて、1つのファイルまたは多くのファイルで実行できる一連の変更を構築し、2.7またはDjangoを壊すことなくほとんどの作業を実行できることです。適度に絞った2to3パスの後でこれ適用ます。これにより、エディターの残留クリーンアップが残り、テストに合格します。

(オプション)2.7コードで黒の実行を開始します。

コードフォーマッターである黒は、Python 3 ASTを使用して分析を実行します。コードを実行しようとはしませんが、ASTステージに到達できないようにする構文エラーにフラグを立てます。ただし、そこに到達するには、いくつかのPIPインストールグローバルマジックを使用する必要があり、ブラックの有用性を購入する必要があります。

他の人々はそれをやった-彼らから学ぶ。

#155を聞くPython 3に移行するための実際的な手順を実行すると、作業のアイデアが得られます。そのためのショーのリンクを見てください。彼らは、一般的なコードベースで同じgitブランチ上で2.7コードを3.x構文に実行する段階的な調整を含むInstagram(?)の動きについて、引き金になる日まで話し合うのが大好きです。

The Conservative Python 3 Porting Guideも参照してください

Instagramが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側は、フレームワークの重大な変更への露出に依存しいるため、早めに開始するのが最善だと思います。

PS(物議を醸す/個人的な意見)私は6つまたは他の缶詰の2対3ブリッジライブラリをあまり使用しませんでした。

それ私がそれを信頼していないからではなく-サードパーティのライブラリにとっては素晴らしい-むしろ、複雑な永続的な依存関係を追加したくなかったからです(そして、そのドキュメントを読むのが面倒すぎた)。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)、奇妙なものに移動しますが、事前に心配する必要はほとんどありません。


いいアドバイス。Django自体は既にsix互換性レイヤーに使用しているため、移行中にDjangoプロジェクトで使用する場合、これは「複雑な永続的な依存関係を追加する」ことではありません。
ウィム

@wim。私はあなたに同意します。6、しかしそれは視点に依存します。サードパーティのライブラリが付属しているので、要件や全体的な依存関係の点で「コスト」がかからないことはすでに述べました。しかし、私は-多分間違って-それを私のコードの真ん中にある大きなブラックボックス/いぼだと考えました。インスタンス文字列/ユニコード/ベース文字列のテストなどを行っているだけで、それを自分で行う方法を知っている場合は、シムが不要になったときにシムをバックアウトする方法を正確に知っています。ただし、最後に移動します。
JL Peyret、

それはpip install -e ...(小文字で-e)ですよね?
thebjorn

それはおそらくです。修正されます
JL Peyret

3

まずDjango==1.11.26、Python 2とPython 3の両方をサポートするDjangoの最新バージョンであるにアップグレードすることをお勧めします。今のところ、現在のバージョンのPython 2.7をそのまま使用します。

1.10.xと1.11.xのリリースノートをよく読み、非推奨かどうかを確認し、1.9.xコードで機能しなくなったものを修正します。物事は壊れます。Djangoは速く動きます。大規模なDjangoプロジェクトの場合、多くのコード変更が必要になる可能性があり、サードパーティのプラグインやライブラリを多数使用している場合は、それらのバージョンを調整する必要がある場合があります。サードパーティの依存関係の一部はおそらく完全に放棄されているため、代わりのものを見つけるか、機能を削除する必要があります。

各バージョンのアップグレードのリリースノートを見つけるには、「Djangoの新機能」をググってください。ヒットは、すべての非推奨と変更を綿密に文書化します。

Webアプリケーションは、すべてのテストが合格で、Djangoの1.11上で正常に動作することが表示されたら(あなたが行う権利、テストスイートを持っている?)、あなたは同じDjangoのバージョンを維持しながら、Pythonの3の変換を行うことができます。Django 1.11は最大でPython 3.7をサポートしているので、これはターゲットとして適切なバージョンです。バイトとテキストの間の暗黙的な変換がなくなり、多くのPython 2 Webアプリケーションがそれに依存しているため、あらゆる場所でUnicodeが期待されます。

プロジェクトがDjango 1.11とPython 3.7で正常に動作しているように見えたら、以前と同じプロセスに従って、Django 3.0へのアップグレードを検討できます。リリースノートを読み、必要な変更を加え、テストスイートを実行し、チェックアウトします。開発サーバーのwebappを手動で。


1
間違いなく行く方法。テストコードを入手して、2.7と3.xの両方で実行します。で同じgitリポジトリを指す2つの異なるvirtualenvを持つことができますpip install -E。ユニットテストが実行されたら、Django-on-3xのテストの使用を開始し、コードを2と3で引き続き動作させます。コーディングを慎重に行い、2.7ブリッジを焼き付けないように注意してください。たとえば、f文字列はありません-スイッチオーバーは非常にクライマクティック。3.xが完全に安定したら、3.xのみのコードの使用を開始します。利点は、製品2.7が常に切り替えられるまでステップに入るということです。
JL Peyret

2

最初にpy3にアップグレードします。あなたは見てする必要がありますsetup.py安定/ 1.9.xブランチ(上Djangoのレポでhttps://github.com/django/django/blob/stable/1.9.x/setup.py PY3ことを把握するために)サポートされているバージョンは3.4(デッド)および3.5です。

py3.5とDjango 1.9を使用している場合は、目的のバージョンになるまで一度に1つずつアップグレードできます。たとえば、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で停止します。

他のパッケージがある場合は、各ステップで連携するバージョンの組み合わせを見つける必要があります。計画を立てることが重要であり、一度に1つのコンポーネントのみをアップグレードすると、通常は時間を節約できます。

将来のライブラリ(https://python-future.org/)は、py27と3.xの両方で実行するコードが必要である一方で、多くの厄介な状況で役立ちます。6も素晴らしいです。私はあなた自身の互換性レイヤーを転がすことを避けます(なぜ車輪を再発明するのですか?)

可能な場合は、開始する前にユニットテストのカバレッジを最大75〜85%にして、各アップグレードステップの「開始」バージョンと「終了」バージョンの両方で自動テストを確実に設定してください。次のバージョンにアップグレードする前に、Djangoからのすべての警告を読んで修正してください。Djangoは下位互換性をほとんど考慮しないため、通常、アップグレードパスのすべてのマイナーバージョンにアクセスすることをお勧めします(または、少なくとも非互換性」および各マイナーバージョンの非推奨リスト)。

幸運(300 + Klocコードベースをpy27 / dj1.7からアップグレードしているので、私はあなたの痛みを感じます;-)


1
テストカバレッジで+1。これは、ここでの主要なメトリックです。広範囲にわたるコード変更を試すときに本当に役立ちます。これは、TDD Red / Greenテストの愛好家ではない人としてこれを言っています。2.7の結果のベースラインを設定する方法を理解すると、アップグレードがはるかに簡単になります。
JL Peyret、

2

私のプロジェクトにも同じ種類の問題があり、Djangoバージョン2.2.7でpython 3.7.5を試しました。

pythonの最新バージョン3.8またはDjango最新バージョン3.0を使用しないでください。あらゆる種類のバグが原因で、最新バージョンの適切な解決策が得られない可能性があるためです。


これはコメントであるべきです
Bruno

-2

現在のバージョンで撮影してみてください。Python 3.8およびDjango3.0。Sixライブラリは、いくつかの規則の変更に役立ちます。どちらの方法でも、リファクタリングを行う必要があるので、それを最新のものにすることもできます。


3
Djangoのアップグレードを行ったことがありますか?これは単なる希望的な考えです。2.7 / 1.9からPython 3.8とDjango 3.0に直接アクセスすることは事実上不可能です。Django 1.9などのマイナーバージョンを1.10にアップグレードすることも、多くのコード変更が必要なため、難しいプロセスになる可能性があります。
wim

はい、私は完全なリファクタリングを行い、アプリケーションを最新のものにするための贅沢な時間的承認を得たのは当然です。再度、アプリケーションのサイズ、ロジックと時間の制約がほとんど男性のための大きな問題ですが、私は「最善の解決策」や「希望的観測」の私の意見をお勧めしますので、彼らは、アプリケーションのサイズや時間の制約を言及したことはありません。)
デイヴ・

さらに、AnsibleやLTS Ubuntuでの実行についても心配する必要がある場合、Ubuntu 18.04では3.7のサポートが不足していることがわかります。私が聞いているセキュリティポッドキャストでは、3.8がポイントリリースまで少し落ち着くようにアドバイスしています。不必要なリスクがある場合は2. -1にします。
JL Peyret

良いセキュリティポッドキャストの推奨事項はありますか?
Dave

Python secの場合は、listennotes.com / podcasts / talk - python - to - me / …ですが、3.8に対する注意は最近のものだと思います。 Risky Businessは、特に国際関係をフォローしている場合は、優れた楽しいセキュリティポッドキャストです。反対票を投じたことをお詫びしますが、そうです、あなたのケースでうまくいったことは、別の状況で他の誰かを弱体化させるかもしれません。2から3への変換については、listennotes.com / podcasts / talk
me /…を
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.