[Django] #34320: Oracle migrations don't remove CONSTRAINTs

4 views
Skip to first unread message

Django

unread,
Feb 7, 2023, 5:14:35 PM2/7/23
to django-...@googlegroups.com
#34320: Oracle migrations don't remove CONSTRAINTs
-------------------------------------+-------------------------------------
Reporter: Georgi | Owner: nobody
Yanchev |
Type: Bug | Status: new
Component: Database | Version: 4.1
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
**Steps to reproduce:**

1. Use Oracle as a db backend

2. Create a model class:
{{{
class TestModel(models.Model):
looooooooooooooooooooooooooooooooooooooong_name =
models.PositiveIntegerField(default=0)
}}}

3. python manage.py makemigrations
You get a migration file called 0001_initial.py with:
{{{
operations = [
migrations.CreateModel(
name='TestModel',
fields=[
('id', models.BigAutoField(auto_created=True,
primary_key=True, serialize=False, verbose_name='ID')),
('looooooooooooooooooooooooooooooooooooooong_name',
models.PositiveIntegerField(default=0)),
],
),
]

}}}

4. Rename the field in the model:
{{{
class TestModel(models.Model):
renamed_looooooooooooooooooooooooooooooooooooooong_name =
models.PositiveIntegerField(default=0)
}}}

5. python manage.py makemigrations
When asked about whether the field was renamed, say "y".
You get another migrations file
0002_rename_looooooooooooooooooooooooooooooooooooooong_name_testmodel_renamed_loooooooooooooooooooooooooo.py
with:

{{{
operations = [
migrations.RenameField(
model_name='testmodel',
old_name='looooooooooooooooooooooooooooooooooooooong_name',
new_name='renamed_looooooooooooooooooooooooooooooooooooooong_name',
),
]
}}}

6. Migrate db
python manage.py migrate myapp
The queries executed are:

{{{
-- 0001_....py
CREATE TABLE "MYAPP_TESTMODEL" ("ID" NUMBER(19) GENERATED BY DEFAULT ON
NULL AS IDENTITY NOT NULL PRIMARY KEY, "LOOOOOOOOOOOOOOOOOOOOOOOOO8973"
NUMBER(11) NOT NULL CHECK ("LOOOOOOOOOOOOOOOOOOOOOOOOO8973" >= 0))

-- 0002_....py
ALTER TABLE "MYAPP_TESTMODEL" RENAME COLUMN
"LOOOOOOOOOOOOOOOOOOOOOOOOO8973" TO "RENAMED_LOOOOOOOOOOOOOOOOOAFEA"
ALTER TABLE "MYAPP_TESTMODEL" ADD CONSTRAINT
"MYAPP_TES_RENAMED_L_7E971FCA_C" CHECK ("RENAMED_LOOOOOOOOOOOOOOOOOAFEA"
>= 0)
}}}

**Note that we didn't create a constraint when applying 0001, but we did
create one for 0002. So the db schema is not the same as it would be if
0001 and 0002 were squashed**

7. Unapply 0002
python manage.py migrate myapp 0001
Queries are:
{{{
ALTER TABLE "MYAPP_TESTMODEL" RENAME COLUMN
"RENAMED_LOOOOOOOOOOOOOOOOOAFEA" TO "LOOOOOOOOOOOOOOOOOOOOOOOOO8973"
ALTER TABLE "MYAPP_TESTMODEL" ADD CONSTRAINT
"MYAPP_TES_LOOOOOOOO_D76B28D1_C" CHECK ("LOOOOOOOOOOOOOOOOOOOOOOOOO8973"
>= 0)
}}}

**Note that MYAPP_TES_RENAMED_L_7E971FCA_C that was created when 0002 was
applied is not dropped. So now we end up with 2 CONSTRAINTs.**

8. Apply 0002
python migrate myapp 0002

Queries are:

{{{
ALTER TABLE "MYAPP_TESTMODEL" RENAME COLUMN
"LOOOOOOOOOOOOOOOOOOOOOOOOO8973" TO "RENAMED_LOOOOOOOOOOOOOOOOOAFEA"
ALTER TABLE "MYAPP_TESTMODEL" ADD CONSTRAINT
"MYAPP_TES_RENAMED_L_7E971FCA_C" CHECK ("RENAMED_LOOOOOOOOOOOOOOOOOAFEA"
>= 0)
}}}

**Observed:**

The last query fails with:

{{{
django.db.utils.DatabaseError: ORA-02264: name already used by an existing
constraint
}}}

**Expected:**

1. Database schema is the same no matter whether a field was renamed.
2. Obsolete db CONSTRAINTs are dropped.

--
Ticket URL: <https://code.djangoproject.com/ticket/34320>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Reply all
Reply to author
Forward
0 new messages