Migrate the database up to the given targets. Django first needs to create all project states before a migration is (un)applied and in a second step run all the database operations.
(self, targets, plan=None, state=None, fake=False, fake_initial=False)
| 94 | return state |
| 95 | |
| 96 | def migrate(self, targets, plan=None, state=None, fake=False, fake_initial=False): |
| 97 | """ |
| 98 | Migrate the database up to the given targets. |
| 99 | |
| 100 | Django first needs to create all project states before a migration is |
| 101 | (un)applied and in a second step run all the database operations. |
| 102 | """ |
| 103 | # The django_migrations table must be present to record applied |
| 104 | # migrations, but don't create it if there are no migrations to apply. |
| 105 | if plan == []: |
| 106 | if not self.recorder.has_table(): |
| 107 | return self._create_project_state(with_applied_migrations=False) |
| 108 | else: |
| 109 | self.recorder.ensure_schema() |
| 110 | |
| 111 | if plan is None: |
| 112 | plan = self.migration_plan(targets) |
| 113 | # Create the forwards plan Django would follow on an empty database |
| 114 | full_plan = self.migration_plan( |
| 115 | self.loader.graph.leaf_nodes(), clean_start=True |
| 116 | ) |
| 117 | |
| 118 | all_forwards = all(not backwards for mig, backwards in plan) |
| 119 | all_backwards = all(backwards for mig, backwards in plan) |
| 120 | |
| 121 | if not plan: |
| 122 | if state is None: |
| 123 | # The resulting state should include applied migrations. |
| 124 | state = self._create_project_state(with_applied_migrations=True) |
| 125 | elif all_forwards == all_backwards: |
| 126 | # This should only happen if there's a mixed plan |
| 127 | raise InvalidMigrationPlan( |
| 128 | "Migration plans with both forwards and backwards migrations " |
| 129 | "are not supported. Please split your migration process into " |
| 130 | "separate plans of only forwards OR backwards migrations.", |
| 131 | plan, |
| 132 | ) |
| 133 | elif all_forwards: |
| 134 | if state is None: |
| 135 | # The resulting state should still include applied migrations. |
| 136 | state = self._create_project_state(with_applied_migrations=True) |
| 137 | state = self._migrate_all_forwards( |
| 138 | state, plan, full_plan, fake=fake, fake_initial=fake_initial |
| 139 | ) |
| 140 | else: |
| 141 | # No need to check for `elif all_backwards` here, as that condition |
| 142 | # would always evaluate to true. |
| 143 | state = self._migrate_all_backwards(plan, full_plan, fake=fake) |
| 144 | |
| 145 | self.check_replacements() |
| 146 | |
| 147 | return state |
| 148 | |
| 149 | def _migrate_all_forwards(self, state, plan, full_plan, fake, fake_initial): |
| 150 | """ |