Upgrade to Pro — share decks privately, control downloads, hide ads and more …

manage.py 深堀り

manage.py 深堀り

DjangoCongress JP 2022

Avatar for shintaromatsudo

shintaromatsudo

November 12, 2022

Other Decks in Technology

Transcript

  1. Motivation - 動機 • python manage.py test • python manage.py

    migrate          の実装を見に行った。
  2. • Name: 松土 慎太郎 (@shintaromatsudo) • Work: 株式会社RevComm • Python:

    PyCon JP 2022 Staff • Like: ◦ 子どもと遊ぶ ◦ 冒険、挑戦 ◦ アウトドア、スポーツ ◦ (水曜どうでしょう、ディズニー、ラーメン二郎 ) Who am I Who am I - おまえだれよ
  3. • ターゲット ◦ Django を少し使ったことがある人 • 話さないこと ◦ コマンド網羅、ひとつひとつの説明 •

    話すこと ◦ デフォルトコマンドいくつかの中身 ◦ カスタムコマンドの作り方と活用例 • 前提 ◦ バージョンは、3.2を基本に4系で新しく入る機能も少しご紹介。 Overview - 概要
  4. • ターゲット ◦ Django を少し使ったことがある人 • 話さないこと ◦ コマンド網羅、ひとつひとつの説明 •

    話すこと ◦ デフォルトコマンドいくつかの中身 ◦ カスタムコマンドの作り方と活用例 • 前提 ◦ バージョンは、3.2を基本に4系で新しく入る機能も少しご紹介。 Overview - 概要
  5. • ターゲット ◦ Django を少し使ったことがある人 • 話さないこと ◦ コマンド網羅、ひとつひとつの説明 •

    話すこと ◦ デフォルトコマンドいくつかの中身 ◦ カスタムコマンドの作り方と活用例 • 前提 ◦ バージョンは、3.2を基本に4系で新しく入る機能も少しご紹介。 Overview - 概要
  6. • ターゲット ◦ Django を少し使ったことがある人 • 話さないこと ◦ コマンド網羅、ひとつひとつの説明 •

    話すこと ◦ デフォルトコマンドいくつかの中身 ◦ カスタムコマンドの作り方と活用例 • 前提 ◦ バージョンは、3.2を基本に4系で新しく入る機能も少しご紹介。 Overview - 概要
  7. Agenda 1. コマンド紹介 a. コマンドが実行されるまで b. shell c. test d.

    migration関連 2. カスタムコマンド a. 概要 b. 作り方 c. 活用例 manage.py 深堀り
  8. Agenda 1. コマンド紹介 a. コマンドが実行されるまで b. shell c. test d.

    migration関連 2. カスタムコマンド a. 概要 b. 作り方 c. 活用例 manage.py 深堀り
  9. コマンド紹介 - Djangoコマンドが 実行されるまで manage.py ↓ django.core.management.__init__.py execute_from_command_line() ↓ django.core.management.__init__.py

    ManagementUtility クラス execute() ↓ django.core.management.base.py BaseCommand クラス run_from_argv() ↓ self.execute() ↓ self.handle
  10. コマンド紹介 - Djangoコマンドが 実行されるまで manage.py ↓ django.core.management.__init__.py execute_from_command_line() ↓ django.core.management.__init__.py

    ManagementUtility クラス execute() ↓ django.core.management.base.py BaseCommand クラス run_from_argv() ↓ self.execute() ↓ self.handle
  11. manage.py ↓ django.core.management.__init__.py execute_from_command_line() ↓ django.core.management.__init__.py ManagementUtility クラス execute() ↓

    django.core.management.base.py BaseCommand クラス run_from_argv() ↓ self.execute() ↓ self.handle コマンド紹介 - Djangoコマンドが 実行されるまで
  12. manage.py ↓ django.core.management.__init__.py execute_from_command_line() ↓ django.core.management.__init__.py ManagementUtility クラス execute() ↓

    django.core.management.base.py BaseCommand クラス run_from_argv() ↓ self.execute() ↓ self.handle コマンド紹介 - Djangoコマンドが 実行されるまで 長いので抜粋 https://github.com/django/django/blob/stab le/3.2.x/django/core/management/__init__.p y#L334
  13. manage.py ↓ django.core.management.__init__.py execute_from_command_line() ↓ django.core.management.__init__.py ManagementUtility クラス execute() ↓

    django.core.management.base.py BaseCommand クラス run_from_argv() ↓ self.execute() ↓ self.handle コマンド紹介 - Djangoコマンドが 実行されるまで 長いので抜粋 https://github.com/django/django/blob/stab le/3.2.x/django/core/management/base.py# L337
  14. manage.py ↓ django.core.management.__init__.py execute_from_command_line() ↓ django.core.management.__init__.py ManagementUtility クラス execute() ↓

    django.core.management.base.py BaseCommand クラス run_from_argv() ↓ self.execute() ↓ self.handle() コマンド紹介 - Djangoコマンドが 実行されるまで 長いので抜粋 https://github.com/django/django/blob/stab le/3.2.x/django/core/management/base.py# L373
  15. manage.py ↓ django.core.management.__init__.py execute_from_command_line() ↓ django.core.management.__init__.py ManagementUtility クラス execute() ↓

    django.core.management.base.py BaseCommand クラス run_from_argv() ↓ self.execute() ↓ self.handle() コマンド紹介 - Djangoコマンドが 実行されるまで
  16. Agenda 1. コマンド紹介 a. コマンドが実行されるまで b. shell c. test d.

    migration関連 2. カスタムコマンド a. 概要 b. 作り方 c. 活用例 manage.py 深堀り
  17. Agenda 1. コマンド紹介 a. コマンドが実行されるまで b. shell c. test d.

    migration関連 2. カスタムコマンド a. 概要 b. 作り方 c. 活用例 manage.py 深堀り
  18. django.core.management.commands.test.py handle() ↓ test_runner.run_tests() ← get_runner() ↓ django.test.runner.py DiscoverRunner run_tests()

    discoverで対象のtest_caseをまとめ、 test_suiteを作成。 コマンド紹介 - test DiscoverRunner クラス run_tests()
  19. django.core.management.commands.test.py handle() ↓ test_runner.run_tests() ← get_runner() ↓ django.test.runner.py DiscoverRunner run_tests()

    ↓ build_suite() コマンド紹介 - test DiscoverRunner クラス build_suite() https://github.com/django/django/bl ob/stable/3.2.x/django/test/runner.p y#L559
  20. django.core.management.commands.test.py handle() ↓ test_runner.run_tests() ← get_runner() ↓ django.test.runner.py DiscoverRunner run_tests()

    ↓ run_suite(suite) ← build_suite() 作成したtest_suiteを引数に渡し、 run_suite()を実行。 コマンド紹介 - test DiscoverRunner クラス run_tests() django.test.runner.DiscoverRunner unittest.TestSuite
  21. django.core.management.commands.test.py handle() ↓           test_runner.run_tests() ← get_runner() ↓ django.test.runner.py DiscoverRunner

    run_tests() ↓ run_suite(suite) ← build_suite() コマンド紹介 - test DiscoverRunner クラス run_suite()
  22. django.core.management.commands.test.py handle() ↓           test_runner.run_tests() ← get_runner() ↓ django.test.runner.py DiscoverRunner

    run_tests() ↓ run_suite(suite) ← build_suite() ↓ self.test_runner() コマンド紹介 - test DiscoverRunner クラス run_suite()
  23. django.core.management.commands.test.py handle() ↓           test_runner.run_tests() ← get_runner() ↓ django.test.runner.py DiscoverRunner

    run_tests() ↓ run_suite(suite) ← build_suite() ↓ run(suite) ← self.test_runner() コマンド紹介 - test DiscoverRunner クラス run_suite() unittest.TextTestRunner django.test.runner.DiscoverRunner unittest.TestSuite
  24. django.core.management.commands.test.py handle() ↓           test_runner.run_tests() ← get_runner() ↓ django.test.runner.py DiscoverRunner

    run_tests() ↓ run_suite(suite) ← build_suite() ↓ run(suite) ← self.test_runner() ↓ cpython.Lib.unittest.runner.py TextTestRunner run(self, test) コマンド紹介 - test unittest.TextTestRunner クラス run() https://github.com/python/cpython/ blob/3.11/Lib/unittest/runner.py#L192
  25. django.core.management.commands.test.py handle() ↓           test_runner.run_tests() ← get_runner() ↓ django.test.runner.py DiscoverRunner

    run_tests() ↓ run_suite(suite) ← build_suite() ↓ run(suite) ← self.test_runner() ↓ cpython.Lib.unittest.runner.py TextTestRunner run(self, test) コマンド紹介 - test unittest.TextTestRunner クラス run() testはunittest.TestSuite unittest.TestSuite.__call__を見てみよ う。
  26. django.core.management.commands.test.py handle() ↓           test_runner.run_tests() ← get_runner() ↓ django.test.runner.py DiscoverRunner

    run_tests() ↓ run_suite(suite) ← build_suite() ↓ run(suite) ← self.test_runner() ↓ cpython.Lib.unittest.runner.py TextTestRunner run(self, test) ↓ cpython.Lib.unittest.suite.py TestSuite test() == TestSuite.__call__() == TestSuite.run() コマンド紹介 - test unittest.TestSuite クラス https://github.com/python/cpython/ blob/3.11/Lib/unittest/suite.py#L83 unittest.TestSuite.runを実行している。
  27. django.core.management.commands.test.py handle() ↓           test_runner.run_tests() ← get_runner() ↓ django.test.runner.py DiscoverRunner

    run_tests() ↓ run_suite(suite) ← build_suite() ↓ run(suite) ← self.test_runner() ↓ cpython.Lib.unittest.runner.py TextTestRunner run(self, test) ↓ cpython.Lib.unittest.suite.py TestSuite test() == TestSuite.__call__() == TestSuite.run() コマンド紹介 - test unittest.TestSuite クラス run() https://github.com/python/cpython/ blob/3.11/Lib/unittest/suite.py#L102
  28. django.core.management.commands.test.py handle() ↓           test_runner.run_tests() ← get_runner() ↓ django.test.runner.py DiscoverRunner

    run_tests() ↓ run_suite(suite) ← build_suite() ↓ run(suite) ← self.test_runner() ↓ cpython.Lib.unittest.runner.py TextTestRunner run(self, test) ↓ cpython.Lib.unittest.suite.py TestSuite test() == TestSuite.__call__() == TestSuite.run() コマンド紹介 - test unittest.TestSuite クラス run() 自身をforループで回している。 TestSuiteの一つ一つは、 TestSuiteまたはTestCase。 forループでTestCaseを一つ一つ実行。
  29. django.core.management.commands.test.py handle() ↓      test_runner.run_tests() ← get_runner() ↓ django.test.runner.py DiscoverRunner run_tests()

    ↓ run_suite(suite) ← build_suite() ↓ run(suite) ← self.test_runner() ↓ cpython.Lib.unittest.runner.py TextTestRunner run(self, test) ↓ cpython.Lib.unittest.suite.py TestSuite test() == TestSuite.__call__() == TestSuite.run() ↓ django.test.testcase.py TestCase run() コマンド紹介 - test DiscoverRunnerが処理の中心 Pythonのunittestを実行 unittest.TextTestRunner django.test.runner.DiscoverRunner unittest.TestSuite
  30. 引数: • --parallel [N] ◦ 並列処理 ◦ multiprocessingを使用 ◦ test_suite

    が、 ParallelTestSuite になる。 https://github.com/django/django/blob/stable/3.2.x/django/test/runner.py#L351 コマンド紹介 - test
  31. 引数: • --parallel と -b はテストの高速化に一役買うことができる。 • しかし、--parallel と -b

    は同時に使うことができない。 • ただし、それは3系までの話。 コマンド紹介 - test
  32. 引数: • --parallel と -b はテストの高速化に一役買うことができる。 • しかし、--parallel と -b

    は同時に使うことができない。 • ただし、それは3系までの話。 • 4.0から同時実行可能になる。 https://docs.djangoproject.com/en/4.0/releases/4.0/#tests コマンド紹介 - test
  33. Agenda 1. コマンド紹介 a. コマンドが実行されるまで b. shell c. test d.

    migration関連 2. カスタムコマンド a. 概要 b. 作り方 c. 活用例 manage.py 深堀り
  34. • migrate • makemigrations • showmigrations • sqlmigrate • squashmigrations

    • 🆕 optimizemigration コマンド紹介 - migration関連
  35. • migrate • makemigrations • showmigrations • sqlmigrate • squashmigrations

    • 🆕 optimizemigration コマンド紹介 - migration関連
  36. • migrate • migrate <app_label> <migration_name> ◦ <app_label> ▪ 指定したappのみ実行

    ◦ <app_label> <migration_name> ▪ 指定したappの指定したmigrationまで実行 ▪ 0001などprefixで指定できる。zeroは全て未実行の状態に戻す。 コマンド紹介 - migration関連
  37. • migrate • 🆕 --prune ◦ 存在しないマイグレーションを django_migrations テーブルから削 除する。

    ◦ (squashmigrationコマンドで) 削除されたマイグレーションファイル をデータベースに反映するときに使用する。 コマンド紹介 - migration関連
  38. Agenda 1. コマンド紹介 a. コマンドが実行されるまで b. shell c. test d.

    migration関連 2. カスタムコマンド a. 概要 b. 作り方 c. 活用例 manage.py 深堀り
  39. Agenda 1. コマンド紹介 a. コマンドが実行されるまで b. shell c. test d.

    migration関連 2. カスタムコマンド a. 概要 b. 作り方 c. 活用例 manage.py 深堀り
  40. Agenda 1. コマンド紹介 a. コマンドが実行されるまで b. shell c. test d.

    migration関連 2. カスタムコマンド a. 概要 b. 作り方 c. 活用例 manage.py 深堀り
  41. カスタムコマンド - 活用例 • ユーザが活動データをCSVでダウンロードする User ECS (Django) SQS Lambda

    ECS (Django 別タスク) S3 RDS User 1. CSV作成リクエスト 2. キューに登録 4. ECS実行 3. リクエスト 成功 5. DBからデータを取得し、 CSVを作成 S3にアップロード (重い処理) 6. CSV取得
  42. カスタムコマンド - 活用例 • ユーザが活動データをCSVでダウンロードする User ECS (Django) SQS Lambda

    ECS (Django 別タスク) S3 RDS User 1. CSV作成リクエスト 2. キューに登録 4. ECS実行 3. リクエスト 成功 5. DBからデータを取得し、 CSVを作成 S3にアップロード (重い処理) 6. CSV取得
  43. カスタムコマンド - 活用例 • ユーザが活動データをCSVでダウンロードする User ECS (Django) SQS Lambda

    ECS (Django 別タスク) S3 RDS User 1. CSV作成リクエスト 2. キューに登録 4. ECS実行 3. リクエスト 成功 5. DBからデータを取得し、 CSVを作成 S3にアップロード (重い処理) 6. CSV取得
  44. カスタムコマンド - 活用例 • ユーザが活動データをCSVでダウンロードする User ECS (Django) SQS Lambda

    ECS (Django 別タスク) S3 RDS User 1. CSV作成リクエスト 2. キューに登録 4. ECS実行 3. リクエスト 成功 5. DBからデータを取得し、 CSVを作成 S3にアップロード (重い処理) 6. CSV取得
  45. カスタムコマンド - 活用例 • ユーザが活動データをCSVでダウンロードする User ECS (Django) SQS Lambda

    ECS (Django 別タスク) S3 RDS User 1. CSV作成リクエスト 2. キューに登録 4. ECS実行 3. リクエスト 成功 5. DBからデータを取得し、 CSVを作成 S3にアップロード (重い処理) 6. CSV取得 ecs = boto3.client("ecs") ecs.run_task( overrides={ "containerOverrides": [ { "command": ["python", "manage.py", "ohayo"] } ] } )
  46. カスタムコマンド - 活用例 • ユーザが活動データをCSVでダウンロードする User ECS (Django) SQS Lambda

    ECS (Django 別タスク) S3 RDS User 1. CSV作成リクエスト 2. キューに登録 4. ECS実行 3. リクエスト 成功 5. DBからデータを取得し、 CSVを作成 S3にアップロード (時間がかかる処理 ) 6. CSV取得
  47. カスタムコマンド - 活用例 • ユーザが活動データをCSVでダウンロードする User ECS (Django) SQS Lambda

    ECS (Django 別タスク) S3 RDS User 1. CSV作成リクエスト 2. キューに登録 4. ECS実行 3. リクエスト 成功 5. DBからデータを取得し、 CSVを作成 S3にアップロード (時間がかかる処理 ) 6. CSV取得
  48. • コマンド紹介 ◦ shell ▪ appにアクセスできるpythonインタラクティブモード ◦ test ▪ 4系から--parallelと-bを同時実行できる。

    ◦ migration関連 ▪ 自動ロールバックスクリプトはDB操作なので慎重に • カスタムコマンド ◦ 非同期処理に使える。 Wrap up - まとめ
  49. Copyright © 2022 RevComm Inc. Language and tools 言語/ フレームワーク

    インフラ/運用管理 コミュニケーション