Django 로 하여 금 데이터베이스 장 연결 을 지원 하 게 합 니 다. (많은 성능 을 향상 시 킬 수 있 습 니 다.)
Django 의 데이터 베 이 스 는 설정 을 통 해 맞 춤 형 Backend 를 사용 할 수 있 습 니 다. 여기 서부 터 시작 하 겠 습 니 다.
우선 Django 가 가지 고 있 는 백 엔 드 가 어떻게 이 루어 졌 는 지 살 펴 보 자.Django 홈 페이지 에서 MySql 을 가 진 Package 구 조 를 볼 수 있 습 니 다. 여 기 를 클릭 하 십시오. 가서 참배 하 다.
소스 코드 를 보면 Django 는 기본적으로 MySQLdb 의 Connection 과 Cursor 라 는 두 대상 을 봉 인 했 음 을 알 수 있 습 니 다.그리고 백 엔 드 전 체 를 실현 하 는 것 은 현실 적 이지 도 않 고 근본적으로 문 제 를 해결 할 수도 없다.그래서 우 리 는 생각 을 바 꿀 수 있다.모든 데이터베이스 작업 은 Connection 대상 을 가 져 오 는 것 에서 시작 되 며, Connection 대상 을 가 져 오 는 데 는 하나의 입구 만 있 습 니 다. 바로 MySQLdb. connect 라 는 함수 입 니 다.그래서 우 리 는 MySQLdb 라 는 모듈 을 포장 하고 우리 자신의 connect 방법 으로 원래 의 것 을 대체 하면 근원 적 으로 문 제 를 해결 할 수 있 습 니 다.저 희 는 포장 기 내부 에서 MySQLdb 의 Connection 대상 을 유지 하고 긴 연결 을 유지 합 니 다. connect 가 호출 될 때마다 연결 이 존재 하면 기 존 연결 로 돌아 가 는 것 이 완벽 하지 않 습 니까?그래서 우 리 는 분 별로 첫 번 째 해결 방안 을 쓸 수 있다.
proxies = {}
class _DbWrapper():
def __init__(self,module):
self.connection=None #
self.db=module # MySQLdb module
def __getattr__(self, key):
return getattr(self.db, key) #
def connect(self,*argv,**kwargv):
if not self.connection:
self.connection=self.db.connect(*argv,**kwargv)
return _ConnectionWrapper(self.connection)
def manage(module,keepalive=7*3600):
try:
return proxies[module]
except KeyError:
return proxies.setdefault(module,_DbWrapper(module))
위의 코드 를 pool. py 라 는 파일 에 저장 하 세 요.그리고 Django 소스 코드 에 있 는 db / backend / mysql 패 키 지 를 복사 해서 우리 procject 디 렉 터 리 에 mysql 하나만 저장 합 니 다.pool 디 렉 터 리 에그리고 그 중의 base. py 를 수정 하여 맨 위 에 import 부분 을 찾 습 니 다. import MySQLdb as Database 라 는 문장 은 아래 코드 로 바 꿉 니 다.
try:
import MySQLdb as Database
Database = pool.manage(Database)
except ImportError, e:
from django.core.exceptions import ImproperlyConfigured
raise ImproperlyConfigured("Error loading MySQLdb module: %s" % e)
이렇게 해서 우 리 는 자신의 모듈 로 MySQLdb 를 교 체 했 습 니 다. connect 를 하려 고 할 때 연결 이 있다 고 판단 할 때 다시 연결 을 만 들 지 않 습 니 다.
역 을 뛰 어 올 라 보 니 결 과 는 어 떻 습 니까?몇 번 갱신 한 후에 잘못 보고 했다.Why?로 그 를 보면 다음 과 같은 오 류 를 볼 수 있 습 니 다.
Traceback (most recent call last): File “/home/www/.virtualenvs/django13/lib/python2.7/site-packages/gevent/wsgi.py”, line 114, in handle result = self.server.application(env, self.start_response) File “/home/www/.virtualenvs/django13/lib/python2.7/site-packages/django/core/handlers/wsgi.py”, line 275, in __call__ signals.request_finished.send(sender=self.__class__) File “/home/www/.virtualenvs/django13/lib/python2.7/site-packages/django/dispatch/dispatcher.py”, line 172, in send response = receiver(signal=self, sender=sender, **named) File “/home/www/.virtualenvs/django13/lib/python2.7/site-packages/django/db/__init__.py”, line 85, in close_connection conn.close() File “/home/www/.virtualenvs/django13/lib/python2.7/site-packages/django/db/backends/__init__.py”, line 244, in close self.connection.close()
보아하니 우 리 는 MySQLdb 자 체 를 포장 하 는 것 만 으로 는 안 되 는 것 같다. connect 후 Django 는 connection 의 대상 을 얻 은 후에 하고 싶 은 대로 할 수 있다. 그 는 다 쓴 후에 자각 적 으로 껐 다. 왜냐하면 그 는 connect 할 때마다 새로운 connection 대상 을 얻 었 다 고 직감 했 기 때문이다.그래서 우 리 는 반드시 Connection 대상 도 포장 해 야 한다.그래서 업그레이드 후의 해결 방안 코드 는 다음 과 같다.
proxies = {}
class _ConnectionWrapper(object):
"""
Connection
"""
def __init__(self,conn):
self.conn=conn
def close(self):
"""
"""
pass
def __getattr__(self,key):
"""
"""
return getattr(self.conn, key)
class _DbWrapper():
"""
MySQLdb
"""
def __init__(self,module):
self.connection=None #HOLD
self.db=module # MySQLdb
def __getattr__(self, key):
"""
connect
"""
return getattr(self.db, key)
def connect(self,*argv,**kwargv):
if not self.connection:
self.connection=self.db.connect(*argv,**kwargv)
return _ConnectionWrapper(self.connection)
def manage(module):
try:
return proxies[module]
except KeyError:
return proxies.setdefault(module,_DbWrapper(module))
우 리 는 하 나 를 증가 시 켰 다Connection Wrapper 클래스 는 Connection 대상 을 대리 하고 close 함 수 를 차단 합 니 다.역 을 달 려 보 니 이전의 문제 가 발생 하지 않 고 달 리 는 것 도 원활 하 다.하지만 몇 시간 이 지나 자 문제 가 또 생 겼 다.MySQLdb 의 Connection 은 연결 이 8 시간 동안 방치 되면 스스로 끊 어 지 는 문제 가 있 기 때문이다.그러나 이 문 제 를 해결 하 는 것 은 매우 간단 하 다. 우 리 는 연결 이 거의 8 시간 동안 방치 되 어 있 으 면 close 하고 다시 연결 을 만 들 면 되 지 않 겠 는가?그래서 마지막 해결 방안 의 코드 는 다음 과 같다.
import time
proxies = {}
class _ConnectionWrapper(object):
def __init__(self,conn):
self.conn=conn
def close(self):
pass
def __getattr__(self,key):
return getattr(self.conn, key)
class _DbWrapper():
def __init__(self,module,max_idle):
self.connection=None
self.db=module
self.max_idle=max_idle
self.connected=0
def __getattr__(self, key):
return getattr(self.db, key)
def connect(self,*argv,**kwargv):
if not self.connection or time.time()-self.connected>=self.max_idle:
try:
if self.connection:
self.connection.close()
except:
pass
self.connection=self.db.connect(*argv,**kwargv)
self.connected=time.time()
return _ConnectionWrapper(self.connection)
def manage(module,keepalive=7*3600):
try:
return proxies[module]
except KeyError:
return proxies.setdefault(module,_DbWrapper(module,keepalive))
이 문제 가 해결 되자, 세 계 는 마침내 깨끗 해 졌 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.