如何强制Django使用服务名称连接到Oracle

sbo*_*ose 10 python sql oracle django

问:如何指定Django需要使用服务名称而不是SID连接到Oracle DB?

嗨,

我目前正在告诉我的Django配置使用我的SID连接到Oracle.

但是,我需要使用服务名称而不是SID进行连接.

APP_DATABASES={
    'default': {
            'ENGINE': 'django.db.backends.oracle',
            'NAME': 'myservice',
            'USER': 'system',
            'PASSWORD': 'admin123',
            'HOST': '192.168.1.45',
            'PORT': '1699',
    }
}
Run Code Online (Sandbox Code Playgroud)

这很好用.

但是,当我用服务名称替换'NAME'时,如下所示

 'default': {
                'ENGINE': 'django.db.backends.oracle',
                'NAME': 'myservice.bose.com',
                'USER': 'system',
                'PASSWORD': 'admin123',
                'HOST': '192.168.1.45',
                'PORT': '1699',
        }
Run Code Online (Sandbox Code Playgroud)

我得到了

ORA-12505: TNS:listener does not currently know of SID given in connect descriptor
Run Code Online (Sandbox Code Playgroud)

显然Django告诉Oracle使用SID连接,这不是我想要的Django.

如何指定Django需要使用服务而不是SID连接到Oracle DB?

注意:我已经测试了上面提到的服务名称.它在Oracle SQL Developer中运行良好.

谢谢 - 非常感谢领导.

sbo*_*ose 14

谢谢大家,有一个"文档化"的解决方案:

        'default': {
                'ENGINE': 'django.db.backends.oracle',
                'NAME': 'host.db.com:1699/oracle_service.db.com',
                'USER': 'user',
                'PASSWORD': 'pass',
        }
Run Code Online (Sandbox Code Playgroud)

注意:HOST和PORT键需要被排除在字典之外 - 否则Django将尝试连接完整的"NAME"作为SID.


dpa*_*ruk 7

看看nickzam粘贴的代码:

import cx_Oracle as Database

def _connect_string(self):
    settings_dict = self.settings_dict
    if not settings_dict['HOST'].strip():
        settings_dict['HOST'] = 'localhost'
    if settings_dict['PORT'].strip():
        dsn = Database.makedsn(settings_dict['HOST'],
                               int(settings_dict['PORT']),
                               settings_dict['NAME'])
    else:
        dsn = settings_dict['NAME']
    return "%s/%s@%s" % (settings_dict['USER'],
                         settings_dict['PASSWORD'], dsn)
Run Code Online (Sandbox Code Playgroud)

..很明显,如果你没有指定'PORT'参数,'NAME'参数将按原样使用.因此,将Oracle连接字符串作为'NAME'参数传递将起到作用(如果删除'PORT'参数).

基本上这样的东西会起作用:

'default': {
    'ENGINE': 'oraclepool',
    'NAME': '(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=mydbhostname.example.com)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=myservicename.example.com)))',
    'USER': 'scott',
    'PASSWORD': 'tiger',
}
Run Code Online (Sandbox Code Playgroud)

我已经使用SCAN主机名为HOST尝试了这一点,并验证了这也有效.

警告:到目前为止,我的测试仅限于检查连接字符串是否被接受,是否建立连接以及我的应用程序是否成功提供,以及访问数据.在依赖这种配置之前,我会建议更积极的测试8)