How to access tables from a different schema in oracle 11g using django?

戏子无情 提交于 2021-01-29 09:46:36

问题


I have a user named mi_abc in oracle 11g. The user do not have any table in the database but has access to all the tables in another schema sch_abc. When I run a normal select query from sqldeveloper on the sch_abc schema from mi_abc, it works perfectly fine, but when I use django, I am always getting the error:-

django.db.utils.DatabaseError: ORA-00942: table or view does not exist

I tried to set the db_table = sch_abc.tableName and also set db_table = tableName but both gives me the same error. Any clue how to resolve this?

TRACE:-

Traceback (most recent call last):
  File "C:\xxx\xxx\xxx\xxx\xxx\xxx\xxxx\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
    response = get_response(request)
  File "C:\xxx\xxx\xxxx\xxxx\xxxx\Python\Python37\lib\site-packages\django\utils\deprecation.py", line 142, in __call__
    response = self.process_response(request, response)
  File "C:\xxxx\xxxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\contrib\sessions\middleware.py", line 58, in process_response
    request.session.save()
  File "C:\xxx\xxxx\xxxx\xxxx\xxxxx\Python\Python37\lib\site-packages\django\contrib\sessions\backends\db.py", line 81, in save
    return self.create()
  File "C:\xxxx\xxxxx\xxxx\xxxx\xxxxx\Python\Python37\lib\site-packages\django\contrib\sessions\backends\db.py", line 50, in create
    self._session_key = self._get_new_session_key()
  File "C:\xxxx\xxxxx\xxxxx\xxxxx\xxxx\Python\Python37\lib\site-packages\django\contrib\sessions\backends\base.py", line 164, in _get_new_session_key
    if not self.exists(session_key):
  File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\contrib\sessions\backends\db.py", line 46, in exists
    return self.model.objects.filter(session_key=session_key).exists()
  File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\models\query.py", line 673, in exists
    return self.query.has_results(using=self.db)
  File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\models\sql\query.py", line 517, in has_results
    return compiler.has_results()
  File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\models\sql\compiler.py", line 858, in has_results
    return bool(self.execute_sql(SINGLE))
  File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\models\sql\compiler.py", line 899, in execute_sql
    raise original_exception
  File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\models\sql\compiler.py", line 889, in execute_sql
    cursor.execute(sql, params)
  File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\utils\six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\backends\oracle\base.py", line 497, in execute
    return self.cursor.execute(query, self._param_generator(params))
django.db.utils.DatabaseError: ORA-00942: table or view does not exist

回答1:


Well, I resolved the issue and let me tell you there is no straight way to do it in django. The problem with my application was, I was using the authetication features of django and also session handling. All these tables are created by django directly on the initial migration. So, there is no existence of them in the models.py file that you can simply append the schema name and ask your application to connect to the table of that schema.

What I ended up doing is, I created private synonyms to all the tables of the other schema which actually contained those tables. If you do this, you don't have to change anything in your django code. Your application will simply work because oracle will do the dirty work of actually connecting to the proper table. You will merely call the table in your application as if its your own. In this way when django looks for tables like django_session, auth_user etc, it simply queries it like it always does and oracle redirects it to the actual tables present in another schema.

Hope this helps people who face this issue in the future.




回答2:


This is by no means officially supported, but this works in Postgres:

class Meta:
    managed = False
    db_table = 'schema\".\"table'

It took some trial and error for Postgres, but you can probably do something similar for Oracle. This is because the Postgres engine quotes object names, and this fakes the quoting mechanism out.

UPDATE:

After doing some digging, I found this for Oracle (modified for Python 3):

class Meta:
    db_table = '"SCHEMA"."TABLE_NAME"'

Source: https://code.djangoproject.com/ticket/14136

I would recommend keeping managed = False unless you really know what you're doing. Good luck!




回答3:


You can set the required schema, before executing the command. and then go back to public schema once the queryset is processed.

from django.db import connection
connection.set_schema(schema_name)


来源:https://stackoverflow.com/questions/54543466/how-to-access-tables-from-a-different-schema-in-oracle-11g-using-django

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!