#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 [email protected].
To post to this group, send email to [email protected].
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