django 와 데이터 베 이 스 를 길 게 연결 합 니 다.
한 번 은 권한 문 제 를 처리 할 때 소스 코드 를 계속 추 삭 했 습 니 다. 저 는 dbroute 를 사용 하여 권한 을 제어 하기 때문에 마지막 으로 이 db (구체 적 인 디 렉 터 리: / usr / local / lib / python 2.7 / dist - packages / django / db / init. py) 를 찾 았 습 니 다. 안에 있 는 코드 는 연결 에 관 한 것 이 있 습 니 다. 보이 지 않 고 모 르 겠 습 니 다. 본 후에 국화 가 꽉 끼 었 습 니 다.내 가 갈 게!원래 django 는 조회 할 때마다 데이터 베 이 스 를 한 번 씩 연결 하고 조회 가 끝 난 후에 바로 꺼 버 려 서 작가 가 어떻게 생각 하 는 지 모 르 겠 어 요.매번 조회 할 때마다 연결 을 만 드 는 데 시간 이 많이 걸 리 지 않 습 니까?원본 코드 는 다음 과 같 습 니 다:
from django.conf import settings
from django.core import signals
from django.core.exceptions import ImproperlyConfigured
from django.db.utils import (ConnectionHandler, ConnectionRouter,
load_backend, DEFAULT_DB_ALIAS, DatabaseError, IntegrityError)
__all__ = ('backend', 'connection', 'connections', 'router', 'DatabaseError',
'IntegrityError', 'DEFAULT_DB_ALIAS')
if settings.DATABASES and DEFAULT_DB_ALIAS not in settings.DATABASES:
raise ImproperlyConfigured("You must define a '%s' database" % DEFAULT_DB_ALIAS)
connections = ConnectionHandler(settings.DATABASES)
router = ConnectionRouter(settings.DATABASE_ROUTERS)
# `connection`, `DatabaseError` and `IntegrityError` are convenient aliases
# for backend bits.
# DatabaseWrapper.__init__() takes a dictionary, not a settings module, so
# we manually create the dictionary from the settings, passing only the
# settings that the database backends care about. Note that TIME_ZONE is used
# by the PostgreSQL backends.
# We load all these up for backwards compatibility, you should use
# connections['default'] instead.
class DefaultConnectionProxy(object):
"""
Proxy for accessing the default DatabaseWrapper object's attributes. If you
need to access the DatabaseWrapper object itself, use
connections[DEFAULT_DB_ALIAS] instead.
"""
def __getattr__(self, item):
return getattr(connections[DEFAULT_DB_ALIAS], item)
def __setattr__(self, name, value):
return setattr(connections[DEFAULT_DB_ALIAS], name, value)
connection = DefaultConnectionProxy()
backend = load_backend(connection.settings_dict['ENGINE'])
# Register an event that closes the database connection
# when a Django request is finished.
def close_connection(**kwargs):
# Avoid circular imports
from django.db import transaction
for conn in connections:
# If an error happens here the connection will be left in broken
# state. Once a good db connection is again available, the
# connection state will be cleaned up.
transaction.abort(conn)
connections[conn].close()
signals.request_finished.connect(close_connection)
# Register an event that resets connection.queries
# when a Django request is started.
def reset_queries(**kwargs):
for conn in connections.all():
conn.queries = []
signals.request_started.connect(reset_queries)
# Register an event that rolls back the connections
# when a Django request has an exception.
def _rollback_on_exception(**kwargs):
from django.db import transaction
for conn in connections:
try:
transaction.rollback_unless_managed(using=conn)
except DatabaseError:
pass
signals.got_request_exception.connect(_rollback_on_exception)
닫 힌 신 호 를 받 은 후 바로 닫 습 니 다. 사실은 django 요청 이 있 을 때마다 한 번 연결 하고 조회 합 니 다.인터넷 에서 자 료 를 찾 아 보 니 어떤 사람 이 이렇게 해결 했다.
django 프로젝트 의init__.py 파일 에 다음 코드 를 추가 하여 구현 합 니 다:
from django.core import signals
from django.db import close_connection
# ,
signals.request_finished.disconnect(close_connection)
그것 이 사용 하 는 원 리 는 마지막 줄 코드 와 관련 된 Signal 대상 이 고 그 중에서 disconnect 방법 도 있어 서 신호 관 계 를 취소 하 는 것 에 대응 합 니 다.
나 는 그의 실현 에 따라 하면 안 된다 는 것 을 알 았 다. 몇 시간 동안 방치 한 후에 도 백 스테이지 를 여 는 데 10 초 정도 걸 렸 다.제 가 사용 하 는 것 은 fastcgi 로 django 를 실행 하기 때 문 입 니 다. 아마도 django 는 움직임 이 없 을 때 fastcgi 가 그것 을 걸 었 기 때문에 다시 연결 을 만 들 것 입 니 다.슈퍼 비 서 드 를 사용 하면 실행 되 지 않 을 것 입 니 다.
이 방법 이 안 되 는 이상 소스 코드 를 다시 한 번 살 펴 보 니 backends 디 렉 터 리 아래 에 my sql, Oacle, postgresql 이 있 습 니 다.psycopg 2, sqlite 3 등 을 선택 하여 msql 을 선택 하여 base. py 파일 을 보 러 들 어 갑 니 다.django 는 MySQLdb 를 직접 봉인 하 는 것 을 발 견 했 습 니 다. MySQLdb 대상 을 만 들 때마다 한 번 씩 연결 되 었 습 니 다.스 레 드 풀 처럼 한꺼번에 여러 개의 MySQLdb 대상 을 만 들 수 있 습 니까?답 은 긍정 적 이다.sqlalchemy 는 데이터 베 이 스 를 길 게 연결 할 수 있 는 pool 이 있 습 니 다. 이 파일 의 Database 를 sqlalchemy pool 로 직접 바 꿉 니 다.물론 원본 코드 를 폭력 적 으로 수정 해 서 는 안 된다.이 모듈 은 데이터 베 이 스 를 연결 하 는 데 사용 되 기 때문에 독립 할 수 있 습 니 다.사실 아주 간단 합 니 다. base. py 파일 몇 군데 만 수정 하면 됩 니 다.실현 방법 은 다음 과 같다.
django / db / backends / my sql 디 렉 터 리 에 있 는 파일 을 모두 복사 하여 프로젝트 의 libs / my sql 아래 에 놓 고 base. py 파일 을 수정 합 니 다.찾아내다
try:
import MySQLdb as Database
except ImportError as e:
from django.core.exceptions import ImproperlyConfigured
raise ImproperlyConfigured("Error loading MySQLdb module: %s" % e)
이 코드 는 아래 에 추가 합 니 다:
from sqlalchemy import pool
Database = pool.manage(Database)
거의 다 됐어 요.더 고치 고 싶 으 면 찾 아 라.
self.connection = Database.connect(**kwargs)
주석 을 달 고 추가 하 다.
self.connection = Database.connect(
host=kwargs.get('host', '127.0.0.1'),
port=kwargs.get('port', 3306),
user=kwargs['user'],
db=kwargs['db'],
passwd=kwargs['passwd'],
use_unicode=kwargs['use_unicode'],
charset='utf8'
)
settings. py 의 데이터베이스 설정 을 수정 하고 django. db. backends. mysql 을 libs. mysql 로 변경 합 니 다.이로써 세상 은 많이 좋아 졌 다.정충 이 머리 에 들 어가 면: 훑 어 봐, 세상 이 더 아름 답 다 는 것 을 알 게 될 거 야.
성명: 본 블 로그 도http://descusr.cnblogs.com/p/3566935.html모두 오리지널 입 니 다.