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:
{{{
#!python
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
{{{
#!python
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.)
--
Ticket URL: <https://code.djangoproject.com/ticket/24407>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_better_patch: => 0
* has_patch: 1 => 0
* needs_docs: => 0
* needs_tests: => 0
* stage: Unreviewed => Accepted
Comment:
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. Since `app_label` is supposed to be all
lower case and `model_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:
{{{#!python
# django/db/backends/oracle/introspection.py
def get_table_list(self, cursor):
cursor.execute("SELECT TABLE_NAME FROM USER_TABLES")
return [row[0].lower() for row in cursor.fetchall()]
}}}
and for 1.8+
{{{#!python
# django/db/backends/oracle/introspection.py
def get_table_list(self, cursor):
cursor.execute("SELECT TABLE_NAME, 't' FROM USER_TABLES UNION ALL "
"SELECT VIEW_NAME, 'v' FROM USER_VIEWS")
return [TableInfo(row[0].lower(), row[1]) for row in
cursor.fetchall()]
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/24407#comment:1>
* keywords: => oracle
Comment:
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.
--
Ticket URL: <https://code.djangoproject.com/ticket/24407#comment:2>
Comment (by CarstenF):
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.)
--
Ticket URL: <https://code.djangoproject.com/ticket/24407#comment:3>
Comment (by MarkusH):
FWIW this is also a bit related to #24337.
--
Ticket URL: <https://code.djangoproject.com/ticket/24407#comment:4>
* status: new => closed
* resolution: => fixed
Comment:
Fixed in 530dd193f2a1c791c703f3f961e2296cbb316bf9.
--
Ticket URL: <https://code.djangoproject.com/ticket/24407#comment:5>