Ticket #5415: db_signal_r6702.patch
File db_signal_r6702.patch, 9.1 KB (added by , 17 years ago) |
---|
-
django/db/__init__.py
1 1 import os 2 2 from django.conf import settings 3 from django.core import signals 3 from django.core import signals as core_signals 4 4 from django.core.exceptions import ImproperlyConfigured 5 5 from django.dispatch import dispatcher 6 6 from django.utils.functional import curry … … 54 54 55 55 # Register an event that closes the database connection 56 56 # when a Django request is finished. 57 dispatcher.connect(connection.close, signal= signals.request_finished)57 dispatcher.connect(connection.close, signal=core_signals.request_finished) 58 58 59 # Register an event that resets connection.queries60 # when a Django request is started.61 def reset_queries():62 connection.queries = []63 dispatcher.connect(reset_queries, signal=signals.request_started)64 65 59 # Register an event that rolls back the connection 66 60 # when a Django request has an exception. 67 61 def _rollback_on_exception(): 68 62 from django.db import transaction 69 63 transaction.rollback_unless_managed() 70 dispatcher.connect(_rollback_on_exception, signal= signals.got_request_exception)64 dispatcher.connect(_rollback_on_exception, signal=core_signals.got_request_exception) -
django/db/signals.py
1 query_execute = object() -
django/db/backends/util.py
1 1 import datetime 2 from django.db import signals 3 from django.dispatch import dispatcher 2 4 import md5 3 5 from time import time 4 6 … … 7 9 except ImportError: 8 10 from django.utils import _decimal as decimal # for Python 2.3 9 11 10 class Cursor DebugWrapper(object):12 class CursorSignalWrapper(object): 11 13 def __init__(self, cursor, db): 12 14 self.cursor = cursor 13 15 self.db = db # Instance of a BaseDatabaseWrapper subclass … … 18 20 return self.cursor.execute(sql, params) 19 21 finally: 20 22 stop = time() 21 sql = self.db.ops.last_executed_query(self.cursor, sql, params) 22 self.db.queries.append({ 23 'sql': sql, 24 'time': "%.3f" % (stop - start), 25 }) 23 dispatcher.send(signal=signals.query_execute, sender=self, sql=sql, params=params, time=stop-start) 26 24 27 25 def executemany(self, sql, param_list): 28 26 start = time() … … 30 28 return self.cursor.executemany(sql, param_list) 31 29 finally: 32 30 stop = time() 33 self.db.queries.append({ 34 'sql': '%s times: %s' % (len(param_list), sql), 35 'time': "%.3f" % (stop - start), 36 }) 31 # XXX: Should this be a special signal that only gets called once for efficiency? 32 for params in param_list: 33 dispatcher.send(signal=signals.query_execute, sender=self, sql=sql, params=params, time=stop-start) 37 34 38 35 def __getattr__(self, attr): 39 36 if attr in self.__dict__: … … 41 38 else: 42 39 return getattr(self.cursor, attr) 43 40 41 def __iter__(self): 42 return iter(self.cursor) 43 44 44 45 ############################################### 45 46 # Converters from database (string) to Python # 46 47 ############################################### -
django/db/backends/__init__.py
12 12 ops = None 13 13 def __init__(self, **kwargs): 14 14 self.connection = None 15 self.queries = []16 15 self.options = kwargs 16 self.use_signal_cursor = None 17 17 18 18 def _commit(self): 19 19 if self.connection is not None: … … 31 31 def cursor(self): 32 32 from django.conf import settings 33 33 cursor = self._cursor(settings) 34 if settings.DEBUG: 35 return self.make_debug_cursor(cursor) 34 if self.use_signal_cursor or (self.use_signal_cursor == None and settings.DEBUG): 35 from django.db.backends import util 36 cursor = util.CursorSignalWrapper(cursor, self) 36 37 return cursor 38 37 39 38 def make_debug_cursor(self, cursor):39 from django.db.backends import util40 return util.CursorDebugWrapper(cursor, self)41 42 40 class BaseDatabaseFeatures(object): 43 41 allows_group_by_ordinal = True 44 42 allows_unique_and_pk = True -
django/core/context_processors.py
33 33 context_extras = {} 34 34 if settings.DEBUG and request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS: 35 35 context_extras['debug'] = True 36 from django.db import connection37 context_extras['sql_queries'] = connection.queries38 36 return context_extras 39 37 40 38 def i18n(request): -
tests/modeltests/select_related/models.py
7 7 the select-related behavior will traverse. 8 8 """ 9 9 10 from django.db import models 10 from django.db import models, signals 11 from django.dispatch import dispatcher 11 12 12 13 # Who remembers high school biology? 13 14 … … 75 76 obj.save() 76 77 parent = obj 77 78 79 class QueryCounter(object): 80 counter = 0 81 82 @staticmethod 83 def add(): 84 QueryCounter.counter += 1 85 86 @staticmethod 87 def clear(): 88 QueryCounter.counter = 0 89 90 91 def track_query(sender, *args, **kwargs): 92 QueryCounter.add() 93 dispatcher.connect(track_query, signal=signals.query_execute, weak=False) 94 78 95 __test__ = {'API_TESTS':""" 79 96 80 # Set up.81 # The test runner sets settings.DEBUG to False, but we want to gather queries82 # so we'll set it to True here and reset it at the end of the test suite.83 >>> from django.conf import settings84 >>> settings.DEBUG = True85 86 97 >>> create_tree("Eukaryota Animalia Anthropoda Insecta Diptera Drosophilidae Drosophila melanogaster") 87 98 >>> create_tree("Eukaryota Animalia Chordata Mammalia Primates Hominidae Homo sapiens") 88 99 >>> create_tree("Eukaryota Plantae Magnoliophyta Magnoliopsida Fabales Fabaceae Pisum sativum") 89 100 >>> create_tree("Eukaryota Fungi Basidiomycota Homobasidiomycatae Agaricales Amanitacae Amanita muscaria") 90 101 91 102 >>> from django import db 103 >>> db.connection.use_signal_cursor = True 92 104 93 105 # Normally, accessing FKs doesn't fill in related objects: 94 >>> db.reset_queries()106 >>> QueryCounter.clear() 95 107 >>> fly = Species.objects.get(name="melanogaster") 96 108 >>> fly.genus.family.order.klass.phylum.kingdom.domain 97 109 <Domain: Eukaryota> 98 >>> len(db.connection.queries)110 >>> QueryCounter.counter 99 111 8 100 112 101 113 # However, a select_related() call will fill in those related objects without any extra queries: 102 >>> db.reset_queries()114 >>> QueryCounter.clear() 103 115 >>> person = Species.objects.select_related().get(name="sapiens") 104 116 >>> person.genus.family.order.klass.phylum.kingdom.domain 105 117 <Domain: Eukaryota> 106 >>> len(db.connection.queries)118 >>> QueryCounter.counter 107 119 1 108 120 109 121 # select_related() also of course applies to entire lists, not just items. 110 122 # Without select_related() 111 >>> db.reset_queries()123 >>> QueryCounter.clear() 112 124 >>> world = Species.objects.all() 113 125 >>> [o.genus.family for o in world] 114 126 [<Family: Drosophilidae>, <Family: Hominidae>, <Family: Fabaceae>, <Family: Amanitacae>] 115 >>> len(db.connection.queries)127 >>> QueryCounter.counter 116 128 9 117 129 118 130 # With select_related(): 119 >>> db.reset_queries()131 >>> QueryCounter.clear() 120 132 >>> world = Species.objects.all().select_related() 121 133 >>> [o.genus.family for o in world] 122 134 [<Family: Drosophilidae>, <Family: Hominidae>, <Family: Fabaceae>, <Family: Amanitacae>] 123 >>> len(db.connection.queries)135 >>> QueryCounter.counter 124 136 1 125 137 126 138 # The "depth" argument to select_related() will stop the descent at a particular level: 127 >>> db.reset_queries()139 >>> QueryCounter.clear() 128 140 >>> pea = Species.objects.select_related(depth=1).get(name="sativum") 129 141 >>> pea.genus.family.order.klass.phylum.kingdom.domain 130 142 <Domain: Eukaryota> 131 143 132 144 # Notice: one few query than above because of depth=1 133 >>> len(db.connection.queries)145 >>> QueryCounter.counter 134 146 7 135 147 136 >>> db.reset_queries()148 >>> QueryCounter.clear() 137 149 >>> pea = Species.objects.select_related(depth=5).get(name="sativum") 138 150 >>> pea.genus.family.order.klass.phylum.kingdom.domain 139 151 <Domain: Eukaryota> 140 >>> len(db.connection.queries)152 >>> QueryCounter.counter 141 153 3 142 154 143 >>> db.reset_queries()155 >>> QueryCounter.clear() 144 156 >>> world = Species.objects.all().select_related(depth=2) 145 157 >>> [o.genus.family.order for o in world] 146 158 [<Order: Diptera>, <Order: Primates>, <Order: Fabales>, <Order: Agaricales>] 147 >>> len(db.connection.queries)159 >>> QueryCounter.counter 148 160 5 149 150 # Reset DEBUG to where we found it.151 >>> settings.DEBUG = False152 161 """}