What is the best approach to change primary keys in an existing Django app?

前端 未结 8 1632
野的像风
野的像风 2020-11-28 06:23

I have an application which is in BETA mode. The model of this app has some classes with an explicit primary_key. As a consequence Django use the fields and doesn\'t create

8条回答
  •  北海茫月
    2020-11-28 07:18

    I had to migrate some keys in my Django 1.11 application − the old keys were deterministic, based on an external model. Later though, it turned out that this external model might change, so I needed my own UUIDs.

    For reference, I was changing a table of POS-specific wine bottles, as well as a sales table for those wine bottles.

    • I created an extra field on all the relevant tables. In the first step, I needed to introduce fields that could be None, then I generated UUIDs for all of them. Next I applied a change through Django where the new UUID field was marked as unique. I could start migrating all the views etc to use this UUID field as a lookup, so that less would need to be changed during the upcoming, scarier phase of the migration.
    • I updated the foreign keys using a join. (in PostgreSQL, not Django)
    • I replaced all mention of the old keys with the new keys and tested it out in unit tests, since they use their own separate, testing database. This step is optional for cowboys.
    • Going to your PostgreSQL tables, you'll notice that the foreign key constraints have codenames with numbers. You need to drop those constraints and make new ones:

      alter table pos_winesale drop constraint pos_winesale_pos_item_id_57022832_fk;
      alter table pos_winesale rename column pos_item_id to old_pos_item_id;
      alter table pos_winesale rename column placeholder_fk to pos_item_id;
      alter table pos_winesale add foreign key (pos_item_id) references pos_poswinebottle (id);
      alter table pos_winesale drop column old_pos_item_id;
      
    • With the new foreign keys in place, you can then change the primary key, since nothing references it anymore:

      alter table pos_poswinebottle drop constraint pos_poswinebottle_pkey;
      alter table pos_poswinebottle add primary key (id);
      alter table pos_poswinebottle drop column older_key;
      
    • Fake the migration history.

提交回复
热议问题