在幕后 Django 使用 cx_Oracle 库连接到 Oracle 数据库。
来源:https://github.com/django/django/blob/master/django/db/backends/oracle/base.py
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)
函数 cx_Oracle.make_dsn() 支持可选参数 service_name(摘自 cx_Oracle 文档):
cx_Oracle.makedsn(host, port, sid[, service_name])
Return a string suitable for use as the dsn for the connect() method. This string is identical to the strings that are defined by the Oracle names server or defined in the tnsnames.ora file. If you wish to use the service name instead of the sid, do not include a value for the parameter sid and use the keyword parameter service_name instead.
Note
This method is an extension to the DB API definition.
不幸的是,Django 没有在连接时传递service_name 参数。
如果你真的需要它,给 Django 添加功能请求或修补你本地版本的 Django 以支持 SERVICE_NAME 参数(坏主意,你需要自己支持它):
def _connect_string(self):
settings_dict = self.settings_dict
if not settings_dict['HOST'].strip():
settings_dict['HOST'] = 'localhost'
if settings_dict['PORT'].strip():
if not 'SERVICE_NAME' in settings_dict:
dsn = Database.makedsn(settings_dict['HOST'],
int(settings_dict['PORT']),
settings_dict['NAME'])
else:
dsn = Database.makedsn(host=settings_dict['HOST'],
port=int(settings_dict['PORT']),
service_name=settings_dict['SERVICE_NAME'].strip())
else:
dsn = settings_dict['NAME']
return "%s/%s@%s" % (settings_dict['USER'],
settings_dict['PASSWORD'], dsn)
然后将NAME 更改为SERVICE_NAME 变量为您的连接“默认”:
'default': {
'ENGINE': 'django.db.backends.oracle',
'SERVICE_NAME': 'myservice.bose.com',
'USER': 'system',
'PASSWORD': 'admin123',
'HOST': '192.168.1.45',
'PORT': '1699',
}
稍后,我会将其作为拉取请求添加到 Django 源代码。