如何强制 Django 使用服务名称连接到 Oracle
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19246643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I force Django to connect to Oracle using Service Name
提问by sbose
Q : How do specify that Django needs to connect to Oracle DB using the service name and not SID ?
问:如何指定 Django 需要使用服务名称而不是 SID 连接到 Oracle DB?
Hi,
你好,
I am currently telling my Django configuration to connect to Oracle using my SID.
我目前告诉我的 Django 配置使用我的 SID 连接到 Oracle。
However, I'll need to connect using the service name and not the SID.
但是,我需要使用服务名称而不是 SID 进行连接。
APP_DATABASES={
'default': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'myservice',
'USER': 'system',
'PASSWORD': 'admin123',
'HOST': '192.168.1.45',
'PORT': '1699',
}
}
This works fine.
这工作正常。
However, When I replace the 'NAME' with the service name as follows
但是,当我将“NAME”替换为服务名称时,如下所示
'default': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'myservice.bose.com',
'USER': 'system',
'PASSWORD': 'admin123',
'HOST': '192.168.1.45',
'PORT': '1699',
}
I get a
我得到一个
ORA-12505: TNS:listener does not currently know of SID given in connect descriptor
Clearly Django is telling Oracle to connect using the SID which is not what I want Django to do.
显然 Django 告诉 Oracle 使用 SID 进行连接,这不是我希望 Django 做的。
How do specify that Django needs to connect to Oracle DB using the service and not SID ?
如何指定 Django 需要使用服务而不是 SID 连接到 Oracle DB?
Note : I've tested that the service name mentioned above. It works great from Oracle SQL Developer.
注意:我已经测试了上面提到的服务名称。它在 Oracle SQL Developer 中运行良好。
Thanks - would really appreciate leads.
谢谢 - 非常感谢潜在客户。
回答by sbose
Thanks guys, There's a "documented" solution to this:
谢谢大家,有一个“记录在案”的解决方案:
'default': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'host.db.com:1699/oracle_service.db.com',
'USER': 'user',
'PASSWORD': 'pass',
}
Note: The HOST and PORT keys need to be left out of the dictionary - else Django will try connecting with the complete "NAME" as an SID.
注意:HOST 和 PORT 键需要从字典中删除 - 否则 Django 将尝试使用完整的“NAME”作为 SID 进行连接。
回答by dparkeruk
Looking at the code that nickzam pasted:
查看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)
.. it is clear that if you do not specify a 'PORT' parameter, the 'NAME' parameter is used 'as is'. Therefore, passing an Oracle connect string as the 'NAME' parameter will do the trick (if you remove the 'PORT' parameter).
.. 很明显,如果您不指定“PORT”参数,则“NAME”参数将按“原样”使用。因此,将 Oracle 连接字符串作为 'NAME' 参数传递就可以了(如果您删除了 'PORT' 参数)。
Basically something like this will work:
基本上这样的事情会起作用:
'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',
}
I have tried this using a SCAN hostname for HOST and verified that this works too.
我已经尝试使用 HOST 的 SCAN 主机名并验证这也有效。
WARNING: My tests so far have been limited to checking whether the connect string is accepted, a connection is made and my app is served successfully, accessing data. Before relying on this configuration I would advise more aggressive testing 8)
警告:到目前为止,我的测试仅限于检查连接字符串是否被接受、建立连接以及我的应用程序是否成功提供服务,访问数据。在依赖此配置之前,我建议进行更积极的测试 8)
回答by nickzam
Behind the scenes Django uses cx_Oracle library to connect to Oracle database. Source: https://github.com/django/django/blob/master/django/db/backends/oracle/base.py
在幕后,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)
Function cx_Oracle.make_dsn() supports optional parameter service_name (excerpt from cx_Oracle docs):
函数 cx_Oracle.make_dsn() 支持可选参数 service_name(摘自 cx_Oracle 文档):
cx_Oracle.makedsn(host, port, sid[, service_name])
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.
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.
Unfortunately, Django is not passing service_name
parameter on connection.
不幸的是,Django 没有service_name
在连接时传递参数。
If you really need it, add feature request to Django or patch your local version of Django to support SERVICE_NAME parameter (bad idea, you will need to support it by yourself):
如果你真的需要它,向 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)
Then change NAME
to SERVICE_NAME
variable to your connection 'default':
然后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',
}
Later, I am going to add it as a pull request to Django source.
稍后,我会将其添加为 Django 源的拉取请求。
回答by cheow.thianliang
I use tnsnames.ora. It works for me on Django 1.7. These are the steps:
我使用 tnsnames.ora。它在 Django 1.7 上对我有用。这些是步骤:
Add an entry in tnsnames.ora for the connection.
myservice = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.45)(PORT = 1699)) ) (CONNECT_DATA = (SERVICE_NAME = myservice.bose.com) ) )
Change Django database settings to
'default': { 'ENGINE': 'django.db.backends.oracle', 'NAME': 'myservice', 'USER': 'system', 'PASSWORD': 'admin123', }
在 tnsnames.ora 中为连接添加一个条目。
myservice = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.45)(PORT = 1699)) ) (CONNECT_DATA = (SERVICE_NAME = myservice.bose.com) ) )
将 Django 数据库设置更改为
'default': { 'ENGINE': 'django.db.backends.oracle', 'NAME': 'myservice', 'USER': 'system', 'PASSWORD': 'admin123', }
For details, please refer to Connecting Django to Oracle database using service name
回答by caot
Here is the way that works:
这是有效的方法:
myservice =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.45)(PORT = 1699))
)
(CONNECT_DATA =
(SERVICE_NAME = myservice_name)
)
)
myservice = ''.join(trc_scan.split())
'default': {
'ENGINE': 'django.db.backends.oracle',
'NAME': myservice,
'USER': 'someuser',
'PASSWORD': 'somepsw',
}
Don't put any of the following characters into user name and/or password:
不要在用户名和/或密码中输入以下任何字符:
@/(
@/(