如何使用Django从oracle 11g中的其他模式访问表?

时间:2019-02-05 21:38:34

标签: python django django-models oracle11g cx-oracle

我在oracle 11g中有一个名为mi_abc的用户。 用户在数据库中没有任何表,但是可以访问另一个模式sch_abc中的所有表。 当我从mi_abc的sch_abc模式运行来自sqldeveloper的普通选择查询时,它工作得很好,但是当我使用django时,总是出现错误:-

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

我尝试设置db_table = sch_abc.tableName,还设置了db_table = tableName,但是两者都给了我相同的错误。有什么线索可以解决这个问题吗?

跟踪:-

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 :(得分:0)

这绝对不是官方支持,但是可以在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。祝你好运!

答案 1 :(得分:0)

您可以在执行命令之前设置所需的架构。然后在处理查询集后返回到公共架构。

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

答案 2 :(得分:0)

好吧,我解决了这个问题,让我告诉你,在Django中没有直接的方法可以做到这一点。我的应用程序存在的问题是,我正在使用django的认证功能以及会话处理功能。所有这些表都是由django在初始迁移时直接创建的。因此,在models.py文件中不存在它们,您只需添加模式名称并要求您的应用程序连接到该模式的表即可。

我最终要做的是,我为实际上包含这些表的其他模式的所有表创建了私有同义词。如果执行此操作,则无需在Django代码中进行任何更改。您的应用程序将仅能正常工作,因为oracle会完成实际连接到正确表的工作。您将仅在应用程序中调用该表,就好像它是您自己的一样。这样,当django查找django_session,auth_user等表时,它像往常一样简单地查询它,并且oracle将其重定向到另一个模式中存在的实际表。

希望这对将来会遇到此问题的人们有所帮助。