#34151: Adding explicit primary key with different type doesn't update related
ManyToManyFields.
-------------------------------------+-------------------------------------
     Reporter:  STANISLAV LEPEKHOV   |                    Owner:  Carol
                                     |  Naranjo
         Type:  Bug                  |                   Status:  assigned
    Component:  Migrations           |                  Version:  4.1
     Severity:  Normal               |               Resolution:
     Keywords:  migrations pk uuid   |             Triage Stage:  Accepted
  relation                           |
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Comment (by Carol Naranjo):

 Thanks for the details. I was able to reproduce the exact issue in older
 versions of Django (including the reported 4.0.3), psycopg2-binary 2.9.11,
 and the latest PostgreSQL (18.3 as of today). Here are my findings:

 **Behavior with Django 4.0.3 to 5.2.12:**
 I confirmed that in these versions, the migration proceeds but results in
 an inconsistent database state: The relationship table is not updated to
 match the new primary key type and the foreign key is dropped in the many-
 to-many table.

 **Behavior with Django >= 6.0:**
 I tested the same scenario in the latest versions (6.0 and 6.1-dev), and
 the behavior has changed significantly. Instead of a silent failure when
 attempting to run this particular migration (which generates RemoveField
 and AddField operations for the primary key change), the database now
 explicitly blocks the destructive operation with an **InternalError**:
 {{{
 # (0.003) ALTER TABLE "issue34151_place" DROP COLUMN "id"; args=None;
 alias=default
 # ...
 # django.db.utils.InternalError: cannot drop column id of table
 issue34151_place
 # because other objects depend on it
 # DETAIL:  constraint issue34151_storechain_place_id_97554049_fk_issue3415
 on
 # table issue34151_storechain_places depends on column id of table
 issue34151_place
 # HINT:  Use DROP ... CASCADE to drop the dependent objects too.
 }}}

 This is, in my opinion, the correct and expected behavior. By triggering a
 database-level error, Django prevents the creation of the 'broken' state
 described in the original report so **I recommend closing this ticket** as
 the behavior in the latest mainstream-supported versions is consistent
 with expected database integrity standards.

 **Additional Information / Hints for Users**
 In order to perform this type of migration (changing both the name and
 type of a primary key), here are a few considerations:

 - **Manual Migration Steps**: An alternative way to apply this change
 would be writing a migration with RenameField and AlterType operations.
 However, be aware that for this specific example, PostgreSQL would still
 fail to cast a BigInt directly into a UUID. This is a database-level
 requirement for explicit casting, not a bug in Django. If for example the
 type was altered to a compatible format (such as a string/VarChar) instead
 of a UUID, the operation would execute correctly as expected.

 - **The Limits of Automated Migration Generation**: Django migrations
 provide a 'best guess' of the operations required to keep tables and
 relationships consistent. However, according to the documentation ''“some
 of the more complex operations are not autodetectable and are only
 available via a hand-written migration”'' (See
 [https://docs.djangoproject.com/en/6.0/topics/migrations/#migration-files
 link] ) . When these limitations are hit, manual migration adjustments are
 the standard procedure.
-- 
Ticket URL: <https://code.djangoproject.com/ticket/34151#comment:22>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/django-updates/0107019d1a952b16-08c46f2c-d2e1-4575-af89-cc8d849a930f-000000%40eu-central-1.amazonses.com.

Reply via email to