Skip to content

Instantly share code, notes, and snippets.

@kashewnuts
Created February 12, 2024 13:05
Show Gist options
  • Save kashewnuts/2ca1c53f3b73064237ed7968201b147a to your computer and use it in GitHub Desktop.
Save kashewnuts/2ca1c53f3b73064237ed7968201b147a to your computer and use it in GitHub Desktop.

Djangoバージョンアップやることまとめ

TL;DR

  1. 公式ドキュメント Django の新しいバージョンへの更新 で推奨されていることを実施しましょう。
  2. django-upgrade を使うと対応したバージョンに自動で対応できます。
  3. 使用しているPythonやデータベースが移行対象のDjangoで使用できない場合、同時もしくは先んじて対応が必要です。
  4. CI環境を整備して、継続してバージョンアップしやすい環境を保ちましょう。
  5. サードパーティとの戦い編

Djangoのバージョン情報について

  • どのDjangoのバージョンに更新するか決めましょう: LTS(Long Term Support) or 最新
  • 一足飛びにバージョンアップも可能ですが、各機能リリースを段階的に実施する方が対応する差分が小さくなります。
  • $ python -Wa manage.py check で既存の警告を対応しましょう。この時サードパーティパッケージも合わせて対応する必要があるかもしれません。
  • リリースノートDjango Deprecation Timelineにて変更や廃止があった機能がある場合はそちらも対応します。
  • 既存の警告の対応をしたら、新しいバージョンのDjangoをインストールしましょう。 $ pip install -U Django
  • アップデートが完了したらテストを実行しましょう。この際にも-Wa コマンドラインオプションか PYTHONWARNINGS=always 環境変数を使って警告を表示するとよいでしょう。

django-upgrade の活用

  • Pythonコードはdjango-upgrade で自動で書き換えが可能です。
  • 新しい記述方法があった場合、非推奨でなくても書き換えられることがあるので取捨選択しましょう。
  • Pythonファイルが対象となるので、Django Templateやフロントエンドのコードに影響がないかは別途確認しましょう。

Pythonやデータベースのバージョンを確認

  • 移行対象であるDjangoが使用できるPythonやDBのバージョンを確認しておきましょう。
  • 2023年12月でLTSであるDjango4.2の場合、以下のバージョンをサポートしています。
    • Python 3.8〜3.12(Django 4.2.8から)
    • MySQL 8.0以上
    • PostgreSQL 12以上
    • MariaDB 10.4以上
  • サポートしているバージョンに満たない場合、以下の選択肢が考えられます。
    • 先んじてバージョンアップを済ませておく: 影響範囲を絞れる。リリースが複数回なのを許容できるならおすすめ。
    • リリース時に同時にバージョンアップする: リリースは一度で済むが、影響範囲が大きくなるので計画は慎重に。
  • 各バージョンごとの対応
    • Pythonは3系であれば基本的に動作します。しかしバージョンを重ねるうちに非推奨になり、削除されるものもあるので、What's New in Pythonを読んで影響範囲は確認しておくとよいでしょう。
    • MySQLは5.7以前から8.0に移行する場合は、DBだけでなくアプリケーションの変更も必要な場合があるので要検証。
    • PostgreSQL 12に上げれるなら、拡張機能の制約がない限り15まで上げられるはずので検討しましょう。

継続的なバージョンアップ

  • 一度アップデートしてもそれで終わりではありません。不具合やセキュリティパッチがあったときに来づける仕組みを作りましょう。
  • dependabotRenovateを活用して、パッチリリースがあったときに自動でPR(Pull Request)を作ってくれる仕組みを導入しましょう。
  • バグフィックスやセキュリティ対応のPRが作成されたときに、CI/CD環境を整備して自動テストが実行されると影響範囲が確認しやすくなります。

サードパーティパッケージ編

  • これまでDjangoに絞って説明してきましたが、実際には他のサードパーティパッケージも使用していることがあるのでそちらの観点も加えて記載します。
  • 影響範囲に応じて必要最小限に留めるか、なるべくすべてのパッケージをバージョンアップするか検討して進ましょう。

環境準備編

  • 既存のローカル開発環境の内容を確認しましょう。requirements.txtやpyproject.tomlにPythonの依存関係が記述していることが期待されます。
  • 本番環境に近づけた環境を準備しましょう。コンテナで動作している場合、docker compose のような環境を活用できます。
  • OSによってインストールできなかったり、DBやミドルウェアがインストールしていないと pip install できない場合もあるので環境の準備は重要です。

必要最小限のパッケージをアップデートする

  • Djangoに依存するパッケージだけをアップデートすることで、バージョンアップ時の影響範囲を最小化できます。

  • pipdeptree のようなツールを使うことで、Djangoに依存しているパッケージを一覧で表示できるので活用しましょう。

    # Djangoに依存したパッケージ一覧を表示
    $ pipdeptree --reverse --packages django
    Django==4.2.10
    ├── django-anymail==10.2 [requires: Django>=2.0]
    ├── django-appconf==1.0.6 [requires: Django]
    │   └── django-compressor==4.4 [requires: django-appconf>=1.0.3]
    ├── django-debug-toolbar==4.3.0 [requires: Django>=3.2.4]
    ├── django-ical==1.9.2 [requires: Django>=3.2]
    ├── django-otp==1.3.0 [requires: Django>=3.2]
    ├── django-recurrence==1.11.1 [requires: Django>=2.2]
    │   └── django-ical==1.9.2 [requires: django-recurrence>=1.11.1]
    ├── django-silk==5.1.0 [requires: Django>=3.2]
    └── django-storages==1.14.2 [requires: Django>=3.2]
  • それ以外にもDjangoが要求するパッケージのバージョンが更新されていることもあるので、必要に合わせて更新してください。

とりあえず一括で全パッケージをアップデートする

  • プロジェクトでrequirements.txtを用意している場合は、新しくvenv環境を作った後にバージョン情報を指定せず一括でアップデートしましょう。
  • $ pip install -r requirements.txt -c constraints.txt のようにバージョンを固定している場合、 $ pip install -Ur requirements.txt とすれば依存パッケージの記述を変更することなく実行できます。
  • TODO: requirements.txtやpyproject.tomlにパッケージのバージョン情報も含めて記述している場合

パッケージのバージョンアップがされている場合

  • Djangoの場合と同様にパッケージのドキュメントやリリースノートを確認し、アプリケーションへの影響を確認しながら更新しましょう。
  • メジャーバージョンアップが行われていた場合、アプリケーションへの変更も大きいと考えられるのでどこまで対応が必要かは精査が必要です。
  • アプリケーションの影響が無視できない場合は、影響が少ないできるだけ最新のバージョンにすることも検討してください。
    • ex) 現在1.x系のバージョンを使っているが、2.x系での変更が大きいので1.x系の最新バージョンに更新しておく。
  • 最新のバージョンでなく、特定のバージョンを選択した理由などは課題管理システムに記録を残しておくと、次回対応時に役立ちます。
    • ex) OpenSearchのように使用しているミドルウェアで使えるバージョンが固定されている。

パッケージのバージョンアップが止まっている場合

  • そのまま使える場合はテストを通して動作を確認してOKと判断もできますが、 動作しない場合は検討が必要 です。
  • 選択肢としては以下の4つが考えられます。
    1. 作者にPRを送って変更を取り込んでもらう: 代替パッケージがない場合はこれが理想です。他にも同じように困っている人の助けにもなります。
    2. ForkやPatchを当てて自分たちでメンテナンスする: 1が叶わないこともあります。その場合は必要な変更をして使う形になります。ただし本家の更新が再開されたときは差分を吸収するのが大変です。
    3. 別なパッケージに置き換える: 本家の更新は止まっていても、別のパッケージで新しく再出発していたりするケースもあります。その場合はこちらになりますが、アプリケーションの変更が小さいとは限りません。
    4. 自分たちで自作する: 最終手段のように見えますが、Djangoの更新により本体に搭載されている場合もあります。大小ありますがアプリケーションの変更も必要になるでしょう。

参考資料

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment