Ticket #14091: 14091.patch
File 14091.patch, 6.2 KB (added by , 14 years ago) |
---|
-
docs/faq/models.txt
22 22 23 23 ``connection.queries`` includes all SQL statements -- INSERTs, UPDATES, 24 24 SELECTs, etc. Each time your app hits the database, the query will be recorded. 25 Note that the raw SQL logged in ``connection.queries`` may not include26 parameter quoting. Parameter quoting is performed by the database-specific27 backend, and not all backends provide a way to retrieve the SQL after quoting.28 25 26 If you are using the postgresql backend, note that the raw SQL logged in 27 ``connection.queries`` may be invalid, because it does not include parameter 28 quoting. Other database backends, like postgresql_psycopg2, retrieve 29 the SQL after quoting or rebuild it, ensuring it is valid. 30 29 31 .. versionadded:: 1.2 30 32 31 33 If you are using :doc:`multiple databases</topics/db/multi-db>`, you can use the -
django/db/backends/sqlite3/base.py
104 104 def drop_foreignkey_sql(self): 105 105 return "" 106 106 107 def last_executed_query(self, cursor, sql, params): 108 def quote_params(params): 109 sql = 'SELECT ' + ', '.join(['QUOTE(?)'] * len(params)) 110 # use a new cursor instead of the existing cursor wrapper 111 # to avoid recursive logging 112 return cursor.connection.execute(sql, params).fetchone() 113 if isinstance(params, (list, tuple)): 114 params = quote_params(params) 115 else: 116 params = dict(zip(params.keys(), quote_params(params.values()))) 117 return super(DatabaseOperations, self).last_executed_query(cursor, sql, params) 118 107 119 def pk_default_value(self): 108 120 return 'NULL' 109 121 -
django/db/backends/mysql/base.py
189 189 def fulltext_search_sql(self, field_name): 190 190 return 'MATCH (%s) AGAINST (%%s IN BOOLEAN MODE)' % field_name 191 191 192 def last_executed_query(self, cursor, sql, params): 193 # With MySQLdb, cursor objects have an (undocumented) "_last_executed" 194 # attribute where the exact query sent to the database is saved. 195 # See MySQLdb/cursors.py in the source distribution. 196 return cursor._last_executed 197 192 198 def no_limit_value(self): 193 199 # 2**64 - 1, as recommended by the MySQL documentation 194 200 return 18446744073709551615L -
django/db/backends/oracle/base.py
208 208 else: 209 209 return "%s" 210 210 211 def last_executed_query(self, cursor, sql, params): 212 # http://cx-oracle.sourceforge.net/html/cursor.html#Cursor.statement 213 # The DB API definition does not define this attribute. 214 return cursor.statement 215 211 216 def last_insert_id(self, cursor, table_name, pk_name): 212 217 sq_name = get_sequence_name(table_name) 213 218 cursor.execute('SELECT "%s".currval FROM dual' % sq_name) -
django/db/backends/postgresql_psycopg2/base.py
73 73 74 74 class DatabaseOperations(PostgresqlDatabaseOperations): 75 75 def last_executed_query(self, cursor, sql, params): 76 # With psycopg2, cursor objects have a "query" attribute that is the 77 # exact query sent to the database. See docs here: 78 # http://www.initd.org/tracker/psycopg/wiki/psycopg2_documentation#postgresql-status-message-and-executed-query 76 # http://initd.org/psycopg/docs/cursor.html#cursor.query 77 # The query attribute is a Psycopg extension to the DB API 2.0. 79 78 return cursor.query 80 79 81 80 def return_insert_id(self): -
tests/regressiontests/backends/tests.py
2 2 # Unit and doctests for specific database backends. 3 3 import datetime 4 4 5 from django.conf import settings 5 6 from django.core.management.color import no_style 6 7 from django.db import backend, connection, connections, DEFAULT_DB_ALIAS, IntegrityError 7 8 from django.db.backends.signals import connection_created … … 85 86 classes = models.SchoolClass.objects.filter(last_updated__day=20) 86 87 self.assertEqual(len(classes), 1) 87 88 89 class LastExecutedQueryTest(TestCase): 88 90 91 def setUp(self): 92 # connection.queries will not be filled in without this 93 settings.DEBUG = True 94 95 def tearDown(self): 96 settings.DEBUG = False 97 98 @unittest.skipUnless(connection.vendor in ('oracle', 'postgresql', 'sqlite'), 99 "These backends use the standard parameter escaping rules") 100 def test_parameter_escaping(self): 101 # check that both numbers and string are properly quoted 102 list(models.Tag.objects.filter(name="special:\\\"':", object_id=12)) 103 sql = connection.queries[-1]['sql'] 104 self.assertTrue("= 'special:\\\"'':' " in sql) 105 self.assertTrue("= 12 " in sql) 106 107 @unittest.skipUnless(connection.vendor == 'mysql', 108 "MySQL uses backslashes to escape parameters.") 109 def test_parameter_escaping(self): 110 list(models.Tag.objects.filter(name="special:\\\"':", object_id=12)) 111 sql = connection.queries[-1]['sql'] 112 # only this line is different from the test above 113 self.assertTrue("= 'special:\\\\\\\"\\':' " in sql) 114 self.assertTrue("= 12 " in sql) 115 89 116 class ParameterHandlingTest(TestCase): 90 117 def test_bad_parameter_count(self): 91 118 "An executemany call with too many/not enough parameters will raise an exception (Refs #12612)"