Opened 4 hours ago
Last modified 2 hours ago
#37034 assigned Bug
Improve writing migrations how-to add through field on a ManyToManyField
| Reported by: | Clifford Gama | Owned by: | Clifford Gama |
|---|---|---|---|
| Component: | Documentation | Version: | dev |
| Severity: | Normal | Keywords: | migrations, ManyToManyField, through |
| Cc: | Adam Johnson | Triage Stage: | Unreviewed |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
- Inaccurate description of how Django handles this change: The section states that "the default migration will delete the existing table and create a new one". This is not accurate. Django refuses to apply a migration when
through=is added/changed on an existingManyToManyField.
- The through model example does not accurately reflect the database: The current example uses
on_delete=DO_NOTHINGandmodels.UniqueConstraint, whereas Django's auto-generated through tables useCASCADEandunique_together. In other words, future model states will not bear a correct representation of what's in the db.
- The example can be simplified by setting
Meta.db_tableon the new through model to match the existing table name, eliminating the need for aRunSQLrename operation.
The section also suggests using sqlmigrate or dbshell to find the existing table name, which is indirect. The simplest approach is to inspect field.through._meta.db_table before modifying the field.
Incidentally for the case where db_table remains the same, #36803 may allow us to suggest a simpler alternative in the docs, one that does not need to use SeparateDatabaseAndState.
Change History (2)
comment:1 by , 3 hours ago
| Cc: | added |
|---|
comment:2 by , 2 hours ago
As a compromise between demonstrating how to use SeparateDatabaseAndState and demonstrating how to migrate a m2m field's through attribute correctly, I intend to keep the example and mention the alternatives as part of the example. I will show open a PR in a day or so to show what that'd look like.
So from my understanding, this section of the docs was added to add an example of using
SeperateDatabaseAndStaterather than showing the best way to change aManyToManyFieldto use athroughmodel. See https://github.com/django/django/pull/12523 for details.So I suppose my question would be, do you have a better example for using
SeperateDatabaseAndState?