Opened 4 months ago

Last modified 4 months ago

#36401 closed New feature

Adding CompositePrimaryKey to exiting table leads to drop existing PK with not composit PK creation — at Initial Version

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

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 (0)

Note: See TracTickets for help on using tickets.
Back to Top