1

I'm stuck in a weird situation where I have to be using an oracle database along with Django. Before I get started I would like to mention that I run the database from inside a docker container.

The problem that I've stumbled upon is that even though the database is up and running, I initialised a connection with DataGrip to it and it works just fine when it comes to Django everything blows up.

This is how I configured the database inside Django

DATABASES = {
    'default': {
            'ENGINE': 'django.db.backends.oracle',
            'NAME': 'localhost:1521/ORCLCDB.LOCALDOMAIN',
            'USER': 'terkea',
            'PASSWORD': 'test',
    }
}

But when I run

python manage.py makemigrations
python manage.py migrate

it throws up this error

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial...Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\__init__.py", line 371, in execute_from_command_line
    utility.execute()
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\__init__.py", line 365, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\base.py", line 288, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\base.py", line 335, in execute
    output = self.handle(*args, **options)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\commands\migrate.py", line 200, in handle
    fake_initial=fake_initial,
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\migrations\executor.py", line 117, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)      
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\migrations\executor.py", line 147, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\migrations\executor.py", line 250, in apply_migration
    self.recorder.record_applied(migration.app_label, migration.name)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\migrations\recorder.py", line 71, in record_applied
    self.migration_qs.create(app=app, name=name)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\query.py", line 417, in create
    obj.save(force_insert=True, using=self.db)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 729, in save
    force_update=force_update, update_fields=update_fields)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 759, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 842, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 880, in _do_insert
    using=using, raw=raw)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\query.py", line 1125, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1292, in execute_sql
    return self.connection.ops.fetch_returned_insert_id(cursor)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\oracle\operations.py", line 228, in fetch_returned_insert_id
    return int(cursor._insert_id_var.getvalue())
TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'

And yes, I've seen that plenty more people had similar issues to mine. They suggested trying using --fake-initial, but the results are the same. Another thing that I been noticing is that after you first run the commands mentioned previously the DJANGO_CONTENT_TYPE and DJANGO_MIGRATIONS tables will pop up in the database. Then if you run the migration command once again another error pops up saying

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial...Traceback (most recent call last):
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\utils.py", line 83, in _execute
    return self.cursor.execute(sql)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\oracle\base.py", line 500, in execute
    return self.cursor.execute(query, self._param_generator(params))
cx_Oracle.DatabaseError: ORA-00955: name is already used by an existing object

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\__init__.py", line 371, in execute_from_command_line
    utility.execute()
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\__init__.py", line 365, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\base.py", line 288, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\base.py", line 335, in execute
    output = self.handle(*args, **options)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\commands\migrate.py", line 200, in handle
    fake_initial=fake_initial,
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\migrations\executor.py", line 117, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)      
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\migrations\executor.py", line 147, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\migrations\executor.py", line 244, in apply_migration
    state = migration.apply(state, schema_editor)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\migrations\migration.py", line 122, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\migrations\operations\models.py", line 92, in database_forwards
    schema_editor.create_model(model)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\base\schema.py", line 314, in create_model
    self.execute(sql, params or None)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\base\schema.py", line 133, in execute
    cursor.execute(sql, params)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\utils.py", line 100, in execute
    return super().execute(sql, params)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\utils.py", line 77, in _execute_with_wrappers      
    return executor(sql, params, many, context)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\utils.py", line 83, in _execute
    return self.cursor.execute(sql)
  File "C:\Users\Terkea\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\oracle\base.py", line 500, in execute
    return self.cursor.execute(query, self._param_generator(params))
django.db.utils.DatabaseError: ORA-00955: name is already used by an existing object

Has anyone found a fix to it? Because I been looking all over the place for a whole day and I couldn't find any reliable hotfix.

Terchila Marian
  • 2,225
  • 3
  • 25
  • 48

2 Answers2

0

I don't speak Python, but this:

after you first run the commands mentioned previously the DJANGO_CONTENT_TYPE and DJANGO_MIGRATIONS tables will pop up in the database. Then if you run the migration command once again another error pops up saying (...) ORA-00955

means that

  • procedure you run connects to Oracle database and creates certain objects in some user's schema (those would be "tables that pop up")
  • it succeeds the first time you run it because the schema is empty
  • but, when you run it for the second time, I presume that it contains something like

    create table dept (deptno number primary key, 
                       dname varchar2(20));
    create table emp  (empno number, 
                       deptno number constraint fkd references dept (deptno),
                       ename varchar2(20));
    

    As those tables already exist, Oracle complains as ORA-00955 means

ORA-00955: name is already used by an existing object

What to do? One option is to drop all objects at the beginning of the script. Pay attention to possible foreign key constraints (i.e. drop children first, parents next), e.g.

drop table emp;        --> drop it first as it references DEPT
drop table dept;       
create table dept (...);
create table emp  (...);

Possibly simpler option is to drop the whole user and recreate it. That would work, but - if objects from that user are used elsewhere (hint: grants), you might spoil something. Though, I don't think that this is the case here.

Or, of course, rename objects first so that you could create new ones. This option isn't very probable, I presume.

Littlefoot
  • 131,892
  • 15
  • 35
  • 57
  • I also noticed that and thought about it just as you described the problem. But thing is that it doesn't allow me to drop those tables for some reason. – Terchila Marian Mar 10 '20 at 21:35
  • What reason is "some reason"? What happens when you try to drop a table? – Littlefoot Mar 10 '20 at 21:37
  • It just doesn't allow me to delete the respective tables. So I deleted the whole docker container plenty of times, to start a new one which had to be configured from scratch and I've tryed different approaches when initialising the migrations but I always end up with that error ORA-00955 – Terchila Marian Mar 10 '20 at 21:41
  • Well, the message is pretty clear - you're trying to create object whose name has already been used. Which one is it? No idea, you'd have to figure that out yourself, by checking object-by-object. Anyway, I still don't understand **why** you can't **DROP** those tables. What happens when you try to run e.g. `drop table emp;` while connected to that user? What does Oracle say? Any error message? If so, which one? – Littlefoot Mar 10 '20 at 21:43
  • all right so I finally managed to figure it out. Apparently it was due to JetBrains DataGrip, the program that I been using to connect to the database. Anyhow, back to the topic. I've deleted the tables and tried to run `migrate` again. This time it has thrown the first error `TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'` – Terchila Marian Mar 10 '20 at 21:50
  • This isn't Oracle error so I can't assist. See whether this helps: https://stackoverflow.com/questions/38836795/typeerror-int-argument-must-be-a-string-a-bytes-like-object-or-a-number-not – Littlefoot Mar 10 '20 at 22:10
0

All you have to do is Go to your environment folder and open this file 'lib\site-packages\django\db\backends\oracle\base.py'and under DatabaseWrapper class change all 'NVARCHAR' data-type to 'VARCHAR'. After editing delete all migrations and perform migrations and migrate. These worked for me. Hope these works for you too.