これは何
-
いまだに動いているPython2系のスクリプトを3系にアップデートするときの作業(事前準備含む)の備忘メモ
前提
- pyenvを使用してPythonのバージョン管理を行っている
- Dockerやvirtualenv, Pipenvは未使用
概要
- 移行するPythonを決める
- ローカルで検証する
- 本番(stg)でバージョンを上げる
手順
- 以下で簡単に移行手順を示します
事前調査
現在の動作環境を確認
- 使用しているOSによってアップデートする先のPythonのバージョンが限られているので、事前に調査する
- サーバ上で
pyenv install --list
して、移行できるPythonのバージョンを確認する - 以下はLinuxのOSが
Linux: Amazon Linux AMI release 2016.03
だった場合の例
[ec2-user@app]$ pyenv install --list
Available versions:
# 中略
3.6.0
3.6-dev
3.6.1
3.6.2
3.6.3
3.6.4
3.7.0b2
3.7-dev
3.8-dev
# 後略
移行先のPythonバージョンを決定
- 先ほどの
pyenv install --list
でアップデートできるバージョンの中から、Pythonのバージョンを選定する- パッチバージョンの数字の後に
dev
やb*
が入っているものは、stableでないバージョンなので避ける
- パッチバージョンの数字の後に
- Python Developer’s Guideに各バージョンのメンテナンス期限などが書かれているので、EOLができる限り長いものを選ぶ
- 先ほどの
Linux: Amazon Linux AMI release 2016.03
の例では、 上記の理由より3.6.4
にするのが妥当
- Python Developer’s Guide: https://devguide.python.org/#status-of-python-branches
ローカルでの動作検証
Python3系で使用できないロジックの洗い出し
-
futurizeでPythonのコードのアップデートを試みます
- applyされなかったファイルやメソッドをについて検証していきます
- Pythonの公式でも推奨されているやり方っぽいです
- Python 2 から Python 3 への移植: https://docs.python.org/ja/3/howto/pyporting.html#porting-python-2-code-to-python-3
- futurize Py2 to Py2/3: http://python-future.org/automatic_conversion.html#stage-1-safe-fixes
Python3系の記法に自動変換を行ってみる
- [2to3](2to3 - Python 2 から 3 への自動コード変換)というライブラリで、Python2でのみ通用する記法を(ある程度)自動的に3系の記法に変換してくれます
- 3系への影響範囲が大きい場合は、こちらで一気に変換してみても良いかもしれません(過信は禁物、動作検証はすべき)
- これも、Python3の公式ドキュメントで記載されている方法論になります
- 2to3 Python 2 から 3 への自動コード変換: https://docs.python.org/ja/3/library/2to3.html#module-lib2to3
Pythonバージョンの切り替え&スクリプト実行
- 上記のライブラリでのコードやロジックの移行にある程度目処がついたら、実際にローカルで動かしていきます
- 主な順序は「
pyenv
でバージョン切り替え」「ライブラリのインストール」「スクリプトの実行」となります - DBとの接続が必要な部分など、ローカルだけでは完結しないロジックがある場合はスキップするなど、実行可能な部分だけでも実行する
コケた場合のバックアップ方法をメモする
- ローカルで問題なく動作した場合、stgや本番環境のアップデートを行うことになります
- その前に、「仮にPython3のコードでの動作に問題があった場合」の切り戻しオペレーションをドキュメントか何かに記載しておきましょう
- 具体的に想定される切り戻し作業
-
pyenv
で旧バージョンのPythonに切り替え - アップデートしたコードのcommitをrevertする
- 旧バージョンでライブラリをインストールし直す
-
移行実施
- 以降でいよいよ本番のスクリプトのPythonバージョンを変更していきます
- stg環境があればstg環境で先に実施する
Pythonバージョンの切り替え
-
pyenv
でPythonのバージョンを切り替えていきます
# 3.6.4をインストール
$ pyenv install 3.6.4
$ pyenv versions
system
* 2.7 (set by /home/ec2-user/.pyenv/version)
3.6.4 # 追加されているはず
$ pyenv local 3.6.4
$ pyenv rehash
$ pyenv versions
system
2.7 (set by /home/ec2-user/.pyenv/version)
* 3.6.4 # 変更されているはず
$ python --version
Python 3.6.4 # 変更されているはず
ライブラリの再インストール
- Python3環境にライブラリをインストールします
- 以下は
requirements.txt
を用いてインストールする例です
$ pip install -r requirements.txt
Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 (from requests->-r requirements.txt (line 5))
Cache entry deserialization failed, entry ignored
Downloading https://files.pythonhosted.org/packages/e1/e5/df302e8017440f111c11cc41a6b432838672f5a70aa29227bf58149dc72f/urllib3-1.25.9-py2.py3-none-any.whl (126kB)
100% |████████████████████████████████| 133kB 9.1MB/s
Collecting certifi>=2017.4.17 (from requests->-r requirements.txt (line 5))
Cache entry deserialization failed, entry ignored
Cache entry deserialization failed, entry ignored
Downloading https://files.pythonhosted.org/packages/57/2b/26e37a4b034800c960a00c4e1b3d9ca5d7014e983e6e729e33ea2f36426c/certifi-2020.4.5.1-py2.py3-none-any.whl (157kB)
100% |████████████████████████████████| 163kB 7.3MB/s
# 以下略
スクリプトの動作確認
- 手動で動かせるスクリプトの場合は、実際にスクリプトを動かしてみます
- エラーを吐かずに想定通り動作する場合は、移行成功です
- 一応動作ログを取得してファイルに吐き出すなり、ドキュメントに貼り付けておくなりしておくとベストです
[ec2-user@app]$ python main.py