Opened 4 months ago

Last modified 4 months ago

#36401 closed New feature

Adding CompositePrimaryKey to existing table leads to drop existing PK with not composite PK creation — at Version 1

Reported by: Pavel Tyslacki Owned by:
Component: Migrations Version: 5.2
Severity: Normal Keywords:
Cc: Pavel Tyslacki Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Pavel Tyslacki)

When I define new table with CompositePrimaryKey:

class Test1(models.Model):
    pk = models.CompositePrimaryKey("product_id", "order_id")
    product_id = models.BigIntegerField()
    order_id = models.BigIntegerField()
    quantity = models.IntegerField()

if creates table with

        migrations.CreateModel(
            name='Test1',
            fields=[
                ('pk', models.CompositePrimaryKey('product_id', 'order_id', blank=True, editable=False, primary_key=True, serialize=False)),
                ('product_id', models.BigIntegerField()),
                ('order_id', models.BigIntegerField()),
                ('quantity', models.IntegerField()),
            ],
        ),

and final SQL:

CREATE TABLE "blog_test1" ("product_id" bigint NOT NULL, "order_id" bigint NOT NULL, "quantity" integer NOT NULL, PRIMARY KEY ("product_id", "order_id"));

But if I has existing table:

class Test2(models.Model):
    #pk = models.CompositePrimaryKey("product_id", "order_id")
    product_id = models.BigIntegerField()
    order_id = models.BigIntegerField()
    quantity = models.IntegerField()
         migrations.CreateModel(
            name='Test2',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('product_id', models.BigIntegerField()),
                ('order_id', models.BigIntegerField()),
                ('quantity', models.IntegerField()),
            ],
        ),

and try to add CompositePrimaryKey, in this case next migration created:

        migrations.RemoveField(
            model_name='test2',
            name='id',
        ),
        migrations.AddField(
            model_name='test2',
            name='pk',
            field=models.CompositePrimaryKey('product_id', 'order_id', blank=True, editable=False, primary_key=True, serialize=False),
        ),

and migration SQL will look next:

--
-- Remove field id from test2
--
ALTER TABLE "blog_test2" DROP COLUMN "id" CASCADE;
--
-- Add field pk to test2
--
-- (no-op)

in this case old PK will be dropped, but new CompositePrimaryKey will not created.

Expected no matter is model created in one or two steps, final db table will have same PK constraints, eg. CompositePrimaryKey will be created if we add it to existing table.

Issue presented at least in postgres and sqlite.

Change History (1)

comment:1 by Pavel Tyslacki, 4 months ago

Description: modified (diff)
Summary: Adding CompositePrimaryKey to exiting table leads to drop existing PK with not composit PK creationAdding CompositePrimaryKey to existing table leads to drop existing PK with not composite PK creation
Note: See TracTickets for help on using tickets.
Back to Top