Opened 10 years ago
Closed 3 years ago
#24407 closed Bug (fixed)
Initial migration fails if app name has upper-case letters on Oracle
Reported by: | Carsten Fuchs | Owned by: | nobody |
---|---|---|---|
Component: | Migrations | Version: | 1.7 |
Severity: | Normal | Keywords: | oracle |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
In a Django project that was created pre-1.7, did not use South before and was recently upgraded to Django 1.7.4 and is otherwise fine, I was trying to convert it to use migrations, following the docs at https://docs.djangoproject.com/en/1.7/topics/migrations/#adding-migrations-to-apps
Creating the initial migrations with makemigrations
went well, but the first run of migrate
aborted with error "django.db.utils.DatabaseError: ORA-00955: name is already used by an existing object". Please see my post to django-users at https://groups.google.com/forum/#!topic/django-users/lVS24BGFouo for details.
Debugging this quickly brought me to MigrationExecutor.detect_soft_applied()
in django/db/migrations/executor.py
, whose lines 153 to 154 say:
if model._meta.db_table not in self.connection.introspection.get_table_list(self.connection.cursor()): return False
It seems that get_table_list()
returns all lower-case list items, whereas model._meta.db_table
was, in my case, "Lori_aub". Consequently, False
was wrongly returned.
Adding lower()
, i.e. changing this to
if model._meta.db_table.lower() not in self.connection.introspection.get_table_list(self.connection.cursor()): return False
entirely fixed the problem for me! :-)
(Sorry for not having a PR readily available.)
Change History (5)
comment:1 by , 10 years ago
Has patch: | unset |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 10 years ago
Keywords: | oracle added |
---|---|
Summary: | Initial migration fails if app name has upper-case letters → Initial migration fails if app name has upper-case letters on Oracle |
While it is different in symptoms and code-paths, this is essentially the same issue as #20487: The Oracle backend (not Oracle itself) converts names to uppercase on the way into the db, and so it must convert them back to lowercase on the way out -- which, in some cases, is not the correct transformation.
The right workaround for you is, of course, to fake the initial migration. I'm not closing this as a dupe (yet), because the migrations behavior deserves more careful study.
comment:3 by , 10 years ago
Ok, many thanks for your feedback! I was not aware that the scope of this issue is actually much broader...
(In hindsight, it is clear to me that faking the initial migration was the right workaround, but I deliberately did not use --fake
because from a user's perspective, knowing little about the implementation details, I did not want to forgo any other issues it might have identified. I did not expect any, but it seemed like a good extra verification step.)
comment:5 by , 3 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Fixed in 530dd193f2a1c791c703f3f961e2296cbb316bf9.
Your fix will break on all other backends as they keep the table name as given (e.g.
AppLabel_modelname
). As far as I know Oracle converts table names to all uppercase internally. Sinceapp_label
is supposed to be all lower case andmodel_name
=object_name.lower()
the problem is with not explicitly making the app_label lower case.This is the
get_table_list()
implementation in 1.7 for Oracle:and for 1.8+