#24892: Django migrations don't escape uppercase table name in "" when using
postgres backend when changing Integer  field to Auto field
----------------------------+--------------------------------------
     Reporter:  jbzdak      |                    Owner:  nobody
         Type:  Bug         |                   Status:  new
    Component:  Migrations  |                  Version:  1.8
     Severity:  Normal      |               Resolution:
     Keywords:              |             Triage Stage:  Unreviewed
    Has patch:  0           |      Needs documentation:  0
  Needs tests:  0           |  Patch needs improvement:  0
Easy pickings:  0           |                    UI/UX:  1
----------------------------+--------------------------------------
Changes (by jbzdak):

 * needs_better_patch:   => 0
 * needs_tests:   => 0
 * needs_docs:   => 0


Old description:

> To cut long story short: in a small application I had models using domain
> level primary keys, that were strings, I wanted to introduce synthetic
> primary keys.
>
> Here are models before migration (I have updated `int_pk` to be unique).
>
> {{{
> class Foo(models.Model):
>
>   string_pk = models.CharField(
>     max_length=10,
>     primary_key= True
>   )
>
>   int_pk = models.IntegerField(
>     null=True
>   )
>
>   class Meta:
>
>     db_table = "FOO"
>
> }}}
>
> Models after migration:
>
> {{{
> class Foo(models.Model):
>
>   string_pk = models.CharField(
>     max_length=10,
>     unique = True
>   )
>
>   int_pk = models.AutoField(
>     primary_key=True
>   )
>
>   class Meta:
>
>     db_table = "FOO"
> }}}
>
> Generated migration:
>
> {{{
>
> class Migration(migrations.Migration):
>
>     dependencies = [
>         ('testapp', '0002_foo_int_pk'),
>     ]
>
>     operations = [
>         migrations.AlterField(
>             model_name='foo',
>             name='int_pk',
>             field=models.AutoField(primary_key=True, serialize=False),
>         ),
>         migrations.AlterField(
>             model_name='foo',
>             name='string_pk',
>             field=models.CharField(max_length=10, unique=True),
>         ),
>     ]
> }}}
>
> This migration fails with following error:
>
> {{{
> django.db.utils.ProgrammingError: relation "foo" does not exist
> }}}
>
> Generated SQL is:
>
> {{{
> ALTER TABLE "FOO" ALTER COLUMN "int_pk" TYPE integer, ALTER COLUMN
> "int_pk" SET NOT NULL;
> DROP SEQUENCE IF EXISTS FOO_int_pk_seq CASCADE;
> CREATE SEQUENCE FOO_int_pk_seq;
> ALTER TABLE FOO ALTER COLUMN int_pk SET DEFAULT
> nextval('FOO_int_pk_seq');
> SELECT setval('FOO_int_pk_seq', MAX(int_pk)) FROM FOO;
> ALTER TABLE "FOO" ADD CONSTRAINT "FOO_int_pk_5b283460a20ef820_uniq"
> UNIQUE ("int_pk");
> ALTER TABLE "FOO" DROP CONSTRAINT "FOO_pkey";
> ALTER TABLE "FOO" ADD CONSTRAINT "FOO_int_pk_5b283460a20ef820_pk" PRIMARY
> KEY ("int_pk");
> }}}
>
> Error is caused by wollowing two lines:
>
> {{{
> ALTER TABLE FOO ALTER COLUMN int_pk SET DEFAULT
> nextval('FOO_int_pk_seq');
> SELECT setval('FOO_int_pk_seq', MAX(int_pk)) FROM FOO;
> }}}
> In these lines `FOO` should be replaced by `"FOO"`

New description:

 To cut long story short: in a small application I had models using domain
 level primary keys, that were strings, I wanted to introduce synthetic
 primary keys.

 Here are models before migration (I have updated `int_pk` to be unique).

 {{{
 class Foo(models.Model):

   string_pk = models.CharField(
     max_length=10,
     primary_key= True
   )

   int_pk = models.IntegerField(
     null=True
   )

   class Meta:

     db_table = "FOO"

 }}}

 Models after migration:

 {{{
 class Foo(models.Model):

   string_pk = models.CharField(
     max_length=10,
     unique = True
   )

   int_pk = models.AutoField(
     primary_key=True
   )

   class Meta:

     db_table = "FOO"
 }}}

 Generated migration:

 {{{

 class Migration(migrations.Migration):

     dependencies = [
         ('testapp', '0002_foo_int_pk'),
     ]

     operations = [
         migrations.AlterField(
             model_name='foo',
             name='int_pk',
             field=models.AutoField(primary_key=True, serialize=False),
         ),
         migrations.AlterField(
             model_name='foo',
             name='string_pk',
             field=models.CharField(max_length=10, unique=True),
         ),
     ]
 }}}

 This migration fails with following error:

 {{{
 django.db.utils.ProgrammingError: relation "foo" does not exist
 }}}

 Generated SQL is:

 {{{
 ALTER TABLE "FOO" ALTER COLUMN "int_pk" TYPE integer, ALTER COLUMN
 "int_pk" SET NOT NULL;
 DROP SEQUENCE IF EXISTS FOO_int_pk_seq CASCADE;
 CREATE SEQUENCE FOO_int_pk_seq;
 ALTER TABLE FOO ALTER COLUMN int_pk SET DEFAULT nextval('FOO_int_pk_seq');
 SELECT setval('FOO_int_pk_seq', MAX(int_pk)) FROM FOO;
 ALTER TABLE "FOO" ADD CONSTRAINT "FOO_int_pk_5b283460a20ef820_uniq" UNIQUE
 ("int_pk");
 ALTER TABLE "FOO" DROP CONSTRAINT "FOO_pkey";
 ALTER TABLE "FOO" ADD CONSTRAINT "FOO_int_pk_5b283460a20ef820_pk" PRIMARY
 KEY ("int_pk");
 }}}

 Error is caused by wollowing two lines:

 {{{
 ALTER TABLE FOO ALTER COLUMN int_pk SET DEFAULT nextval('FOO_int_pk_seq');
 SELECT setval('FOO_int_pk_seq', MAX(int_pk)) FROM FOO;
 }}}

 In these lines `FOO` should be replaced by `"FOO"`.

 I use Django `1.8.2`.

--

--
Ticket URL: <https://code.djangoproject.com/ticket/24892#comment:1>
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 django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/064.ca6e2d1826ce179e623d62e74545e60a%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to