서비스 이름을 사용하여 Django가 Oracle에 연결하도록 강제하는 방법
Q: 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',
}
}
이것은 잘 작동합니다.
그러나 'NAME'을 다음과 같이 서비스 이름으로 바꿀 때
'default': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'myservice.bose.com',
'USER': 'system',
'PASSWORD': 'admin123',
'HOST': '192.168.1.45',
'PORT': '1699',
}
나는
ORA-12505: TNS:listener does not currently know of SID given in connect descriptor
분명히 Django는 Oracle에게 SID를 사용하여 연결하라고 말하고 있습니다. 이는 Django가 원하는 것이 아닙니다.
Django가 SID가 아닌 서비스를 사용하여 Oracle DB에 연결해야 한다고 어떻게 지정합니까?
참고: 위에서 언급한 서비스 이름을 테스트했습니다.Oracle SQL Developer에서 매우 잘 작동합니다.
감사합니다. 리드를 주시면 정말 감사하겠습니다.
여러분 감사합니다. 이에 대한 "문서화된" 솔루션이 있습니다.
'default': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'host.db.com:1699/oracle_service.db.com',
'USER': 'user',
'PASSWORD': 'pass',
}
참고: HOST 및 PORT 키는 사전에서 제외해야 합니다. 그렇지 않으면 Django는 완전한 "NAME"을 SID로 연결하려고 시도할 것입니다.
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)
'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',
}
호스트에 대한 스캔 호스트 이름을 사용하여 이 작업을 시도해 보았는데 이것도 작동하는지 확인했습니다.
경고: 지금까지 제 테스트는 연결 문자열이 허용되고, 연결이 되고, 앱이 성공적으로 작동하는지, 데이터에 액세스하는지 확인하는 것으로 제한되었습니다.이 구성에 의존하기 전에 보다 적극적인 테스트를 수행하는 것이 좋습니다.8)
저는 tnsnames.ora를 사용합니다.장고 1.7에서 작동합니다.단계는 다음과 같습니다.
연결에 대한 항목을 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', }
자세한 내용은 서비스 이름을 사용하여 Django를 Oracle 데이터베이스에 연결을 참조하십시오.
뒤에서 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.
안타깝게도 장고는 합격하지 못합니다.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 source에 pull request로 추가할 예정입니다.
작동 방식은 다음과 같습니다.
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',
}
사용자 이름 및/또는 암호에 다음 문자를 입력하지 마십시오.
@/(
언급URL : https://stackoverflow.com/questions/19246643/how-do-i-force-django-to-connect-to-oracle-using-service-name
'programing' 카테고리의 다른 글
SQL 데이터베이스 또는 파일에 로그를 저장하는 것이 더 효율적입니까? (0) | 2023.08.27 |
---|---|
MariaDB/MySQL이 갑자기 충돌하여 다시 시작되지 않습니다. (0) | 2023.08.27 |
마스터 슬레이브 토폴로지에서 두 데이터 센터를 구성하려면 어떻게 해야 합니까? (0) | 2023.08.27 |
내용 항목을 텍스트 파일로 만드는 스크립트 (0) | 2023.08.27 |
PowerShell을 읽는 방법.PSD1 파일 안전 (0) | 2023.08.27 |