#34320 closed Bug (fixed)
Renaming fields with truncated names don't remove old constraints on Oracle.
Reported by: | Georgi Yanchev | Owned by: | Mohamed Nabil Rady |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 4.1 |
Severity: | Normal | Keywords: | oracle |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Steps to reproduce:
- Use Oracle as a db backend
- Create a model class:
class TestModel(models.Model): looooooooooooooooooooooooooooooooooooooong_name = models.PositiveIntegerField(default=0)
- 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)), ], ), ]
- Rename the field in the model:
class TestModel(models.Model): renamed_looooooooooooooooooooooooooooooooooooooong_name = models.PositiveIntegerField(default=0)
- 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', ), ]
- 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
- 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.
- 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:
- Database schema is the same no matter whether a field was renamed.
- Obsolete db CONSTRAINTs are dropped.
Change History (13)
comment:1 by , 22 months ago
Summary: | Oracle migrations don't remove CONSTRAINTs → Oracle rename field migrations don't remove CONSTRAINTs |
---|
comment:2 by , 22 months ago
Summary: | Oracle rename field migrations don't remove CONSTRAINTs → Oracle rename field migrations don't remove old CONSTRAINTs |
---|
comment:3 by , 22 months ago
Keywords: | oracle added |
---|---|
Summary: | Oracle rename field migrations don't remove old CONSTRAINTs → Renaming fields with truncated names don't remove old constraints on Oracle. |
Triage Stage: | Unreviewed → Accepted |
comment:4 by , 21 months ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:5 by , 21 months ago
Has patch: | set |
---|
comment:6 by , 21 months ago
Needs tests: | set |
---|
comment:7 by , 21 months ago
Needs tests: | unset |
---|---|
Triage Stage: | Accepted → Ready for checkin |
Thanks for the report. As far as I'm aware, the main reason is that
BaseDatabaseSchemaEditor._constraint_names()
doesn't use truncated column names.