Как получить доступ к таблицам из другой схемы в Oracle 11g, используя Django? - PullRequest
0 голосов
/ 06 февраля 2019

У меня есть пользователь с именем mi_abc в Oracle 11g.Пользователь не имеет таблицы в базе данных, но имеет доступ ко всем таблицам в другой схеме sch_abc.Когда я запускаю обычный запрос на выборку из sqldeveloper для схемы sch_abc из mi_abc, он отлично работает, но когда я использую django, я всегда получаю сообщение об ошибке: -

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

Я попытался установить db_table = sch_abc.tableName, а также установить db_table = tableName, но оба из них дают мне ту же ошибку.Любая подсказка, как решить эту проблему?

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

Ответы [ 3 ]

0 голосов
/ 06 февраля 2019

Вы можете установить необходимую схему перед выполнением команды.и затем вернитесь к общедоступной схеме после обработки набора запросов.

from django.db import connection
connection.set_schema(schema_name)
0 голосов
/ 07 февраля 2019

Ну, я решил проблему и позвольте мне сказать вам, что нет прямого способа сделать это в Django.Проблема с моим приложением заключалась в том, что я использовал функции аутентификации django, а также обработку сессий.Все эти таблицы создаются django непосредственно при начальной миграции.Таким образом, их нет в файле models.py, так что вы можете просто добавить имя схемы и попросить ваше приложение подключиться к таблице этой схемы.

В итоге я создалчастные синонимы ко всем таблицам другой схемы, которая фактически содержала эти таблицы.Если вы сделаете это, вам не нужно ничего менять в своем коде django.Ваше приложение будет просто работать, потому что oracle сделает грязную работу по фактическому подключению к нужной таблице.Вы просто вызовете таблицу в своем приложении, как если бы она была вашей.Таким образом, когда django ищет такие таблицы, как django_session, auth_user и т. Д., Он просто запрашивает его, как всегда, и oracle перенаправляет его на фактические таблицы, присутствующие в другой схеме.

Надеюсь, что это помогает людям, которые сталкиваются с этой проблемой вбудущее.

0 голосов
/ 06 февраля 2019

Это ни в коем случае не поддерживается официально, но в Postgres это работает:

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

Для Postgres потребовалось несколько проб и ошибок, но вы, вероятно, можете сделать что-то подобное для Oracle.Это происходит потому, что движок Postgres цитирует имена объектов, и это подделывает механизм цитирования.

ОБНОВЛЕНИЕ:

После некоторых копаний янашел это для Oracle (модифицирован для Python 3):

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

Источник: https://code.djangoproject.com/ticket/14136

Я бы порекомендовал оставить managed = False, если вы действительно не знаете, что делаете.Удачи!

...