Ticket #5106: backend-refactoring-v2.patch
File backend-refactoring-v2.patch, 70.3 KB (added by , 17 years ago) |
---|
-
django/contrib/auth/models.py
=== modified file 'django/contrib/auth/models.py'
1 1 from django.core import validators 2 2 from django.core.exceptions import ImproperlyConfigured 3 from django.db import backend,connection, models3 from django.db import connection, models 4 4 from django.contrib.contenttypes.models import ContentType 5 5 from django.utils.encoding import smart_str 6 6 from django.utils.translation import ugettext_lazy as _ … … 210 210 AND gp.%s = ug.%s 211 211 AND ct.%s = p.%s 212 212 AND ug.%s = %%s""" % ( 213 backend.quote_name('app_label'), backend.quote_name('codename'),214 backend.quote_name('auth_permission'), backend.quote_name('auth_group_permissions'),215 backend.quote_name('auth_user_groups'), backend.quote_name('django_content_type'),216 backend.quote_name('id'), backend.quote_name('permission_id'),217 backend.quote_name('group_id'), backend.quote_name('group_id'),218 backend.quote_name('id'), backend.quote_name('content_type_id'),219 backend.quote_name('user_id'),)213 connection.ops.quote_name('app_label'), connection.ops.quote_name('codename'), 214 connection.ops.quote_name('auth_permission'), connection.ops.quote_name('auth_group_permissions'), 215 connection.ops.quote_name('auth_user_groups'), connection.ops.quote_name('django_content_type'), 216 connection.ops.quote_name('id'), connection.ops.quote_name('permission_id'), 217 connection.ops.quote_name('group_id'), connection.ops.quote_name('group_id'), 218 connection.ops.quote_name('id'), connection.ops.quote_name('content_type_id'), 219 connection.ops.quote_name('user_id'),) 220 220 cursor.execute(sql, [self.id]) 221 221 self._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()]) 222 222 return self._group_perm_cache -
django/contrib/contenttypes/generic.py
=== modified file 'django/contrib/contenttypes/generic.py'
4 4 5 5 from django import oldforms 6 6 from django.core.exceptions import ObjectDoesNotExist 7 from django.db import backend7 from django.db import connection 8 8 from django.db.models import signals 9 9 from django.db.models.fields.related import RelatedField, Field, ManyToManyRel 10 10 from django.db.models.loading import get_model … … 167 167 model = rel_model, 168 168 instance = instance, 169 169 symmetrical = (self.field.rel.symmetrical and instance.__class__ == rel_model), 170 join_table = backend.quote_name(self.field.m2m_db_table()),171 source_col_name = backend.quote_name(self.field.m2m_column_name()),172 target_col_name = backend.quote_name(self.field.m2m_reverse_name()),170 join_table = connection.ops.quote_name(self.field.m2m_db_table()), 171 source_col_name = connection.ops.quote_name(self.field.m2m_column_name()), 172 target_col_name = connection.ops.quote_name(self.field.m2m_reverse_name()), 173 173 content_type = ContentType.objects.get_for_model(self.field.model), 174 174 content_type_field_name = self.field.content_type_field_name, 175 175 object_id_field_name = self.field.object_id_field_name -
django/core/management.py
=== modified file 'django/core/management.py'
59 59 60 60 def _get_installed_models(table_list): 61 61 "Gets a set of all models that are installed, given a list of existing tables" 62 from django.db import backend, models62 from django.db import connection, models 63 63 all_models = [] 64 64 for app in models.get_apps(): 65 65 for model in models.get_models(app): 66 66 all_models.append(model) 67 if backend.uses_case_insensitive_names:68 converter = lambda x: 67 if connection.capabilities.uses_case_insensitive_names: 68 converter = lambda x:x.upper() 69 69 else: 70 70 converter = lambda x: x 71 71 return set([m for m in all_models if converter(m._meta.db_table) in map(converter, table_list)]) … … 152 152 153 153 Returns list_of_sql, pending_references_dict 154 154 """ 155 from django.db import backend, models 155 from django.db import connection, models 156 157 ops, capabilities = connection.ops, connection.capabilities 158 quote_name = ops.quote_name 156 159 157 160 opts = model._meta 158 161 final_output = [] … … 166 169 # database columns in this table. 167 170 continue 168 171 # Make the definition (e.g. 'foo VARCHAR(30)') for this field. 169 field_output = [style.SQL_FIELD( backend.quote_name(f.column)),172 field_output = [style.SQL_FIELD(quote_name(f.column)), 170 173 style.SQL_COLTYPE(col_type)] 171 174 field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or ''))) 172 if f.unique and (not f.primary_key or backend.allows_unique_and_pk):175 if f.unique and (not f.primary_key or capabilities.allows_unique_and_pk): 173 176 field_output.append(style.SQL_KEYWORD('UNIQUE')) 174 177 if f.primary_key: 175 178 field_output.append(style.SQL_KEYWORD('PRIMARY KEY')) 176 if tablespace and backend.supports_tablespaces and (f.unique or f.primary_key) and backend.autoindexes_primary_keys: 179 if tablespace and capabilities.supports_tablespaces and (f.unique or f.primary_key) \ 180 and capabilities.autoindexes_primary_keys: 177 181 # We must specify the index tablespace inline, because we 178 182 # won't be generating a CREATE INDEX statement for this field. 179 field_output.append( backend.get_tablespace_sql(tablespace, inline=True))183 field_output.append(ops.get_tablespace_sql(tablespace, inline=True)) 180 184 if f.rel: 181 185 if f.rel.to in known_models: 182 186 field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \ 183 style.SQL_TABLE( backend.quote_name(f.rel.to._meta.db_table)) + ' (' + \184 style.SQL_FIELD( backend.quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')' +185 backend.get_deferrable_sql()187 style.SQL_TABLE(quote_name(f.rel.to._meta.db_table)) + ' (' + \ 188 style.SQL_FIELD(quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')' + 189 ops.get_deferrable_sql() 186 190 ) 187 191 else: 188 192 # We haven't yet created the table to which this field … … 190 194 pr = pending_references.setdefault(f.rel.to, []).append((model, f)) 191 195 table_output.append(' '.join(field_output)) 192 196 if opts.order_with_respect_to: 193 table_output.append(style.SQL_FIELD( backend.quote_name('_order')) + ' ' + \197 table_output.append(style.SQL_FIELD(quote_name('_order')) + ' ' + \ 194 198 style.SQL_COLTYPE(models.IntegerField().db_type()) + ' ' + \ 195 199 style.SQL_KEYWORD('NULL')) 196 200 for field_constraints in opts.unique_together: 197 201 table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' % \ 198 ", ".join([ backend.quote_name(style.SQL_FIELD(opts.get_field(f).column)) for f in field_constraints]))202 ", ".join([quote_name(style.SQL_FIELD(opts.get_field(f).column)) for f in field_constraints])) 199 203 200 full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + style.SQL_TABLE( backend.quote_name(opts.db_table)) + ' (']204 full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + style.SQL_TABLE(quote_name(opts.db_table)) + ' ('] 201 205 for i, line in enumerate(table_output): # Combine and add commas. 202 206 full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or '')) 203 207 full_statement.append(')') 204 if opts.db_tablespace and backend.supports_tablespaces:205 full_statement.append( backend.get_tablespace_sql(opts.db_tablespace))208 if opts.db_tablespace and capabilities.supports_tablespaces: 209 full_statement.append(ops.get_tablespace_sql(opts.db_tablespace)) 206 210 full_statement.append(';') 207 211 final_output.append('\n'.join(full_statement)) 208 212 209 if opts.has_auto_field and hasattr(backend, 'get_autoinc_sql'):213 if opts.has_auto_field: 210 214 # Add any extra SQL needed to support auto-incrementing primary keys 211 autoinc_sql = backend.get_autoinc_sql(opts.db_table)215 autoinc_sql = ops.get_autoinc_sql(opts.db_table) 212 216 if autoinc_sql: 213 217 for stmt in autoinc_sql: 214 218 final_output.append(stmt) … … 219 223 """ 220 224 Get any ALTER TABLE statements to add constraints after the fact. 221 225 """ 222 from django.db import backend226 from django.db import connection 223 227 from django.db.backends.util import truncate_name 224 228 229 ops = connection.ops 225 230 final_output = [] 226 if backend.supports_constraints:231 if connection.capabilities.supports_constraints: 227 232 opts = model._meta 228 233 if model in pending_references: 229 234 for rel_class, f in pending_references[model]: … … 236 241 # So we are careful with character usage here. 237 242 r_name = '%s_refs_%s_%x' % (r_col, col, abs(hash((r_table, table)))) 238 243 final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % \ 239 ( backend.quote_name(r_table), truncate_name(r_name, backend.get_max_name_length()),240 backend.quote_name(r_col), backend.quote_name(table), backend.quote_name(col),241 backend.get_deferrable_sql()))244 (ops.quote_name(r_table), truncate_name(r_name, ops.get_max_name_length()), 245 ops.quote_name(r_col), ops.quote_name(table), ops.quote_name(col), 246 ops.get_deferrable_sql())) 242 247 del pending_references[model] 243 248 return final_output 244 249 245 250 def _get_many_to_many_sql_for_model(model): 246 from django.db import backend, models251 from django.db import connection, models 247 252 from django.contrib.contenttypes import generic 248 253 254 ops, capabilities = connection.ops, connection.capabilities 255 quote_name = ops.quote_name 249 256 opts = model._meta 250 257 final_output = [] 251 258 for f in opts.many_to_many: 252 259 if not isinstance(f.rel, generic.GenericRel): 253 260 tablespace = f.db_tablespace or opts.db_tablespace 254 if tablespace and backend.supports_tablespaces and backend.autoindexes_primary_keys:255 tablespace_sql = ' ' + backend.get_tablespace_sql(tablespace, inline=True)261 if tablespace and capabilities.supports_tablespaces and capabilities.autoindexes_primary_keys: 262 tablespace_sql = ' ' + ops.get_tablespace_sql(tablespace, inline=True) 256 263 else: 257 264 tablespace_sql = '' 258 265 table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \ 259 style.SQL_TABLE( backend.quote_name(f.m2m_db_table())) + ' (']266 style.SQL_TABLE(quote_name(f.m2m_db_table())) + ' ('] 260 267 table_output.append(' %s %s %s%s,' % \ 261 (style.SQL_FIELD( backend.quote_name('id')),268 (style.SQL_FIELD(quote_name('id')), 262 269 style.SQL_COLTYPE(models.AutoField(primary_key=True).db_type()), 263 270 style.SQL_KEYWORD('NOT NULL PRIMARY KEY'), 264 271 tablespace_sql)) 265 272 table_output.append(' %s %s %s %s (%s)%s,' % \ 266 (style.SQL_FIELD( backend.quote_name(f.m2m_column_name())),273 (style.SQL_FIELD(quote_name(f.m2m_column_name())), 267 274 style.SQL_COLTYPE(models.ForeignKey(model).db_type()), 268 275 style.SQL_KEYWORD('NOT NULL REFERENCES'), 269 style.SQL_TABLE( backend.quote_name(opts.db_table)),270 style.SQL_FIELD( backend.quote_name(opts.pk.column)),271 backend.get_deferrable_sql()))276 style.SQL_TABLE(quote_name(opts.db_table)), 277 style.SQL_FIELD(quote_name(opts.pk.column)), 278 ops.get_deferrable_sql())) 272 279 table_output.append(' %s %s %s %s (%s)%s,' % \ 273 (style.SQL_FIELD( backend.quote_name(f.m2m_reverse_name())),280 (style.SQL_FIELD(quote_name(f.m2m_reverse_name())), 274 281 style.SQL_COLTYPE(models.ForeignKey(f.rel.to).db_type()), 275 282 style.SQL_KEYWORD('NOT NULL REFERENCES'), 276 style.SQL_TABLE( backend.quote_name(f.rel.to._meta.db_table)),277 style.SQL_FIELD( backend.quote_name(f.rel.to._meta.pk.column)),278 backend.get_deferrable_sql()))283 style.SQL_TABLE(quote_name(f.rel.to._meta.db_table)), 284 style.SQL_FIELD(quote_name(f.rel.to._meta.pk.column)), 285 ops.get_deferrable_sql())) 279 286 table_output.append(' %s (%s, %s)%s' % \ 280 287 (style.SQL_KEYWORD('UNIQUE'), 281 style.SQL_FIELD( backend.quote_name(f.m2m_column_name())),282 style.SQL_FIELD( backend.quote_name(f.m2m_reverse_name())),288 style.SQL_FIELD(quote_name(f.m2m_column_name())), 289 style.SQL_FIELD(quote_name(f.m2m_reverse_name())), 283 290 tablespace_sql)) 284 291 table_output.append(')') 285 if opts.db_tablespace and backend.supports_tablespaces:292 if opts.db_tablespace and capabilities.supports_tablespaces: 286 293 # f.db_tablespace is only for indices, so ignore its value here. 287 table_output.append( backend.get_tablespace_sql(opts.db_tablespace))294 table_output.append(ops.get_tablespace_sql(opts.db_tablespace)) 288 295 table_output.append(';') 289 296 final_output.append('\n'.join(table_output)) 290 297 291 298 # Add any extra SQL needed to support auto-incrementing PKs 292 autoinc_sql = backend.get_autoinc_sql(f.m2m_db_table())299 autoinc_sql = ops.get_autoinc_sql(f.m2m_db_table()) 293 300 if autoinc_sql: 294 301 for stmt in autoinc_sql: 295 302 final_output.append(stmt) … … 298 305 299 306 def get_sql_delete(app): 300 307 "Returns a list of the DROP TABLE SQL statements for the given app." 301 from django.db import backend,connection, models, get_introspection_module308 from django.db import connection, models, get_introspection_module 302 309 from django.db.backends.util import truncate_name 303 310 introspection = get_introspection_module() 304 311 312 ops, capabilities = connection.ops, connections.capabilities 313 quote_name = ops.quote_name 314 305 315 # This should work even if a connection isn't available 306 316 try: 307 317 cursor = connection.cursor() … … 313 323 table_names = introspection.get_table_list(cursor) 314 324 else: 315 325 table_names = [] 316 if backend.uses_case_insensitive_names:326 if capabilities.uses_case_insensitive_names: 317 327 table_name_converter = str.upper 318 328 else: 319 329 table_name_converter = lambda x: x … … 339 349 if cursor and table_name_converter(model._meta.db_table) in table_names: 340 350 # Drop the table now 341 351 output.append('%s %s;' % (style.SQL_KEYWORD('DROP TABLE'), 342 style.SQL_TABLE( backend.quote_name(model._meta.db_table))))343 if backend.supports_constraints and model in references_to_delete:352 style.SQL_TABLE(quote_name(model._meta.db_table)))) 353 if capabilities.supports_constraints and model in references_to_delete: 344 354 for rel_class, f in references_to_delete[model]: 345 355 table = rel_class._meta.db_table 346 356 col = f.column … … 349 359 r_name = '%s_refs_%s_%x' % (col, r_col, abs(hash((table, r_table)))) 350 360 output.append('%s %s %s %s;' % \ 351 361 (style.SQL_KEYWORD('ALTER TABLE'), 352 style.SQL_TABLE( backend.quote_name(table)),353 style.SQL_KEYWORD( backend.get_drop_foreignkey_sql()),354 style.SQL_FIELD(truncate_name(r_name, backend.get_max_name_length()))))362 style.SQL_TABLE(quote_name(table)), 363 style.SQL_KEYWORD(ops.get_drop_foreignkey_sql()), 364 style.SQL_FIELD(truncate_name(r_name, ops.get_max_name_length())))) 355 365 del references_to_delete[model] 356 if model._meta.has_auto_field and hasattr( backend, 'get_drop_sequence'):357 output.append( backend.get_drop_sequence(model._meta.db_table))366 if model._meta.has_auto_field and hasattr(ops, 'get_drop_sequence'): 367 output.append(ops.get_drop_sequence(model._meta.db_table)) 358 368 359 369 # Output DROP TABLE statements for many-to-many tables. 360 370 for model in app_models: … … 362 372 for f in opts.many_to_many: 363 373 if cursor and table_name_converter(f.m2m_db_table()) in table_names: 364 374 output.append("%s %s;" % (style.SQL_KEYWORD('DROP TABLE'), 365 style.SQL_TABLE( backend.quote_name(f.m2m_db_table()))))366 if hasattr( backend, 'get_drop_sequence'):367 output.append( backend.get_drop_sequence("%s_%s" % (model._meta.db_table, f.column)))375 style.SQL_TABLE(quote_name(f.m2m_db_table())))) 376 if hasattr(ops, 'get_drop_sequence'): 377 output.append(ops.get_drop_sequence("%s_%s" % (model._meta.db_table, f.column))) 368 378 369 379 370 380 app_label = app_models[0]._meta.app_label … … 387 397 388 398 def get_sql_flush(): 389 399 "Returns a list of the SQL statements used to flush the database" 390 from django.db import backend 391 statements = backend.get_sql_flush(style, _get_table_list(), _get_sequence_list()) 392 return statements 400 from django.db import connection 401 return connection.ops.get_sql_flush(style, _get_table_list(), _get_sequence_list()) 393 402 get_sql_flush.help_doc = "Returns a list of the SQL statements required to return all tables in the database to the state they were in just after they were installed." 394 403 get_sql_flush.args = '' 395 404 … … 443 452 444 453 def get_sql_sequence_reset(app): 445 454 "Returns a list of the SQL statements to reset sequences for the given app." 446 from django.db import backend, models447 return backend.get_sql_sequence_reset(style, models.get_models(app))455 from django.db import connection, models 456 return connection.ops.get_sql_sequence_reset(style, models.get_models(app)) 448 457 get_sql_sequence_reset.help_doc = "Prints the SQL statements for resetting sequences for the given app name(s)." 449 458 get_sql_sequence_reset.args = APP_ARGS 450 459 … … 460 469 461 470 def get_sql_indexes_for_model(model): 462 471 "Returns the CREATE INDEX SQL statements for a single model" 463 from django.db import backend472 from django.db import connection 464 473 output = [] 465 474 475 ops, capabilities = connection.ops, connection.capabilities 476 466 477 for f in model._meta.fields: 467 if f.db_index and not ((f.primary_key or f.unique) and backend.autoindexes_primary_keys):478 if f.db_index and not ((f.primary_key or f.unique) and capabilities.autoindexes_primary_keys): 468 479 unique = f.unique and 'UNIQUE ' or '' 469 480 tablespace = f.db_tablespace or model._meta.db_tablespace 470 if tablespace and backend.supports_tablespaces:471 tablespace_sql = ' ' + backend.get_tablespace_sql(tablespace)481 if tablespace and capabilities.supports_tablespaces: 482 tablespace_sql = ' ' + ops.get_tablespace_sql(tablespace) 472 483 else: 473 484 tablespace_sql = '' 474 485 output.append( 475 486 style.SQL_KEYWORD('CREATE %sINDEX' % unique) + ' ' + \ 476 style.SQL_TABLE( backend.quote_name('%s_%s' % (model._meta.db_table, f.column))) + ' ' + \487 style.SQL_TABLE(ops.quote_name('%s_%s' % (model._meta.db_table, f.column))) + ' ' + \ 477 488 style.SQL_KEYWORD('ON') + ' ' + \ 478 style.SQL_TABLE( backend.quote_name(model._meta.db_table)) + ' ' + \479 "(%s)" % style.SQL_FIELD( backend.quote_name(f.column)) + \489 style.SQL_TABLE(ops.quote_name(model._meta.db_table)) + ' ' + \ 490 "(%s)" % style.SQL_FIELD(ops.quote_name(f.column)) + \ 480 491 "%s;" % tablespace_sql 481 492 ) 482 493 return output … … 501 512 502 513 def syncdb(verbosity=1, interactive=True): 503 514 "Creates the database tables for all apps in INSTALLED_APPS whose tables haven't already been created." 504 from django.db import backend,connection, transaction, models515 from django.db import connection, transaction, models 505 516 from django.conf import settings 506 517 507 518 disable_termcolors() … … 522 533 # Get a list of all existing database tables, 523 534 # so we know what needs to be added. 524 535 table_list = _get_table_list() 525 if backend.uses_case_insensitive_names:536 if connection.capabilities.uses_case_insensitive_names: 526 537 table_name_converter = str.upper 527 538 else: 528 539 table_name_converter = lambda x: x … … 1249 1260 1250 1261 def createcachetable(tablename): 1251 1262 "Creates the table needed to use the SQL cache backend" 1252 from django.db import backend, connection, transaction, models 1263 from django.db import connection, transaction, models 1264 quote_name = connection.ops.quote_name 1253 1265 fields = ( 1254 1266 # "key" is a reserved word in MySQL, so use "cache_key" instead. 1255 1267 models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True), … … 1259 1271 table_output = [] 1260 1272 index_output = [] 1261 1273 for f in fields: 1262 field_output = [ backend.quote_name(f.name), f.db_type()]1274 field_output = [quote_name(f.name), f.db_type()] 1263 1275 field_output.append("%sNULL" % (not f.null and "NOT " or "")) 1264 1276 if f.unique: 1265 1277 field_output.append("UNIQUE") … … 1268 1280 if f.db_index: 1269 1281 unique = f.unique and "UNIQUE " or "" 1270 1282 index_output.append("CREATE %sINDEX %s_%s ON %s (%s);" % \ 1271 (unique, tablename, f.name, backend.quote_name(tablename),1272 backend.quote_name(f.name)))1283 (unique, tablename, f.name, quote_name(tablename), 1284 quote_name(f.name))) 1273 1285 table_output.append(" ".join(field_output)) 1274 full_statement = ["CREATE TABLE %s (" % backend.quote_name(tablename)]1286 full_statement = ["CREATE TABLE %s (" % quote_name(tablename)] 1275 1287 for i, line in enumerate(table_output): 1276 1288 full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or '')) 1277 1289 full_statement.append(');') … … 1361 1373 "Installs the provided fixture file(s) as data in the database." 1362 1374 from django.db.models import get_apps 1363 1375 from django.core import serializers 1364 from django.db import connection, transaction , backend1376 from django.db import connection, transaction 1365 1377 from django.conf import settings 1366 1378 import sys 1367 1379 … … 1450 1462 (format, fixture_name, humanize(fixture_dir)) 1451 1463 1452 1464 if count[0] > 0: 1453 sequence_sql = backend.get_sql_sequence_reset(style, models)1465 sequence_sql = connection.ops.get_sql_sequence_reset(style, models) 1454 1466 if sequence_sql: 1455 1467 if verbosity > 1: 1456 1468 print "Resetting sequences" … … 1679 1691 if not mod_list: 1680 1692 parser.print_usage_and_exit() 1681 1693 if action not in NO_SQL_TRANSACTION: 1682 from django.db import backend1683 if backend.get_start_transaction_sql():1684 print style.SQL_KEYWORD( backend.get_start_transaction_sql())1694 from django.db import connection 1695 if connection.ops.get_start_transaction_sql(): 1696 print style.SQL_KEYWORD(connections.ops.get_start_transaction_sql()) 1685 1697 for mod in mod_list: 1686 1698 if action == 'reset': 1687 1699 output = action_mapping[action](mod, options.interactive) -
django/db/__init__.py
=== modified file 'django/db/__init__.py'
8 8 settings.DATABASE_ENGINE = 'dummy' 9 9 10 10 try: 11 backend = __import__('django.db.backends.%s.base' % settings.DATABASE_ENGINE, {}, {}, ['']) 11 backend = __import__('django.db.backends.%s.base' % settings.DATABASE_ENGINE, {}, {}, ['']).DatabaseWrapper 12 12 except ImportError, e: 13 13 # The database backend wasn't found. Display a helpful error message 14 14 # listing all possible database backends. … … 16 16 import os 17 17 backend_dir = os.path.join(__path__[0], 'backends') 18 18 available_backends = [f for f in os.listdir(backend_dir) if not f.startswith('_') and not f.startswith('.') and not f.endswith('.py') and not f.endswith('.pyc')] 19 available_backends.sort() 20 if settings.DATABASE_ENGINE not in available_backends: 21 raise ImproperlyConfigured, "%r isn't an available database backend. Available options are: %s" % \ 19 if settings.DATABASE_ENGINE in available_backends: 20 raise # If there's some other error, this must be an error in Django itself. 21 22 try: 23 backend = __import__(settings.DATABASE_ENGINE, {}, {}, ['']) 24 except ImportError, e: 25 available_backends.sort() 26 raise ImproperlyConfigured, "%r isn't an available database backend. Available default options are: %s" % \ 22 27 (settings.DATABASE_ENGINE, ", ".join(map(repr, available_backends))) 23 else: 24 raise # If there's some other error, this must be an error in Django itself. 25 26 get_introspection_module = lambda: __import__('django.db.backends.%s.introspection' % settings.DATABASE_ENGINE, {}, {}, ['']) 27 get_creation_module = lambda: __import__('django.db.backends.%s.creation' % settings.DATABASE_ENGINE, {}, {}, ['']) 28 runshell = lambda: __import__('django.db.backends.%s.client' % settings.DATABASE_ENGINE, {}, {}, ['']).runshell() 29 30 connection = backend.DatabaseWrapper(**settings.DATABASE_OPTIONS) 31 DatabaseError = backend.DatabaseError 32 IntegrityError = backend.IntegrityError 28 29 connection = backend(**settings.DATABASE_OPTIONS) 30 DatabaseError = connection.DatabaseError 31 IntegrityError = connection.IntegrityError 32 get_introspection_module = lambda: connection.introspection 33 get_creation_module = lambda: connection.creation 34 runshell = lambda: connection.runshell() 33 35 34 36 # Register an event that closes the database connection 35 37 # when a Django request is finished. -
django/db/backends/__init__.py
=== modified file 'django/db/backends/__init__.py'
1 from django.utils.functional import curry 2 from django.db.backends import util 3 4 try: 5 # Only exists in Python 2.4+ 6 from threading import local 7 except ImportError: 8 # Import copy of _thread_local.py from Python 2.4 9 from django.utils._threading_local import local 10 11 12 class BaseDatabaseWrapper(local): 13 14 """base class for defining a new db connection wrapper 15 16 Derivatives should add a _cursor method, introspection property, 17 creation property, and a runshell method 18 """ 19 20 ops = capabilities = orm_map = DatabaseError = IntegrityError = None 21 22 def __init__(self, **kwargs): 23 self.connection = None 24 self.queries = [] 25 self.options = kwargs 26 27 def _commit(self): 28 if self.connection is not None: 29 return self.connection.commit() 30 31 def _rollback(self): 32 if self.connection is not None: 33 return self.connection.rollback() 34 35 def close(self): 36 if self.connection is not None: 37 self.connection.close() 38 self.connection = None 39 40 def cursor(self): 41 from django.conf import settings 42 cursor = self._cursor(settings) 43 if settings.DEBUG: 44 return self.make_debug_cursor(cursor) 45 return cursor 46 47 def make_debug_cursor(self, cursor): 48 from django.db.backends import util 49 return util.CursorDebugWrapper(cursor, self) 50 51 def introspection(self): 52 raise NotImplemented(self, 'introspection') 53 54 def creation(self): 55 raise NotImplemented(self, 'creation') 56 57 introspection, creation = map(property, (introspection, creation)) 58 59 def runshell(self): 60 raise NotImplemented(self, 'runshell') 61 62 63 class BackendCapabilities(object): 64 65 defaults = dict(allows_group_by_ordinal=True, allows_unique_and_pk=True, 66 autoindexes_primary_keys=True, needs_datetime_string_cast=True, 67 needs_upper_for_iops=False, supports_constraints=True, 68 supports_tablespaces=False, uses_case_insensitive_names=False) 69 70 def __init__(self, **kwargs): 71 self.__dict__.update(self.defaults) 72 self.__dict__.update(kwargs) 73 74 75 def _throw_unsupported(method, self, *args, **kwargs): 76 raise NotImplemented(self, method) 77 78 class BackendOps(object): 79 80 required_methods = ["%s_sql" % x for x in 81 ('autoinc', 'date_extract', 'date_trunc', 'datetime_cast', 82 'deferrable', 'drop_foreignkey', 'fulltext_search', 'limit_offset', 83 'random_function', 'start_transaction', 'tablespace')] 84 required_methods += ['last_insert_id', 'max_name_length', 85 'pk_default_value', 'sequence_name', 'get_trigger_name'] 86 required_methods = ["get_%s" % x for x in required_methods] 87 required_methods = tuple(required_methods) 88 # listcomps leak variables; we don't need 'x' in the namespace 89 targets = [curry(_throw_unsupported, x) for x in required_methods] 90 locals().update(zip(required_methods, targets)) 91 for x in ('sequence_reset', 'flush'): 92 x = 'get_sql_%s' % x 93 required_methods += (x,) 94 locals()[x] = curry(_throw_unsupported, x) 95 96 del x, targets 97 98 def quote_name(name): 99 if name.startswith(self.start_quote) and name.endswith(self.end_quote): 100 return name # already quoted. 101 return '%s%s%s' % (self.start_quote, name, self.end_quote) 102 103 quote_name = staticmethod(quote_name) 104 105 dictfetchone = staticmethod(util.dictfetchone) 106 dictfetchmany = staticmethod(util.dictfetchmany) 107 dictfetchall = staticmethod(util.dictfetchall) 108 109 # list of methods to pull from old style db layout 110 methods = required_methods + ('get_drop_sequence', 'quote_name', 111 'dictfetchone', 'dictfetchmany', 'dictfetchall',) 112 113 def __init__(self, quote_chars='""'): 114 self.start_quote, self.end_quote = quote_chars[0:2] 115 116 117 class OldLayoutBaseDatabaseWrapper(BaseDatabaseWrapper): 118 119 """ 120 Convenience class used for mapping <=0.96 style backend 121 layouts into current form. 122 123 Generally speaking, you want BaseDatabaseWrapper, not this class. 124 """ 125 126 def __init__(self, *args, **kwargs): 127 super(OldLayoutBaseDatabaseWrapper, self).__init__(*args, **kwargs) 128 mod = __import__(self.__class__.__module__, {}, {}, ['']) 129 d = BackendCapabilities.defaults.copy() 130 for k, v in d.iteritems(): 131 if hasattr(mod, k): 132 d[k] = getattr(mod, k) 133 # generate a few mappings via inspection of the module. 134 self.capabilities = BackendCapabilities(**d) 135 self.orm_map = mod.OPERATOR_MAPPING.copy() 136 self.ops = ops = BackendOps() 137 for op in ops.methods: 138 if hasattr(mod, op): 139 setattr(ops, op, getattr(mod, op)) 140 self.DatabaseError = mod.DatabaseError 141 self.IntegrityError = mod.IntegrityError 142 143 144 def _base_namespace(self): 145 # when py2.4 is the default, convert this to a rsplit limit=1 146 return '.'.join(self.__class__.__module__.split(".")[:-1]) 147 148 def introspection(self): 149 return __import__(self._base_namespace + '.introspection', {}, {}, ['']) 150 151 def creation(self): 152 return __import__(self._base_namespace + '.creation', {}, {}, ['']) 153 154 def runshell(self): 155 return __import__(self._base_namespace + '.client', {}, {}, ['']).runshell 156 157 _base_namespace, introspection, creation, runshell = map(property, 158 (_base_namespace, introspection, creation, runshell)) -
django/db/backends/ado_mssql/base.py
=== modified file 'django/db/backends/ado_mssql/base.py'
48 48 return res 49 49 Database.convertVariantToPython = variantToPython 50 50 51 try: 52 # Only exists in Python 2.4+ 53 from threading import local 54 except ImportError: 55 # Import copy of _thread_local.py from Python 2.4 56 from django.utils._threading_local import local 57 58 class DatabaseWrapper(local): 59 def __init__(self, **kwargs): 60 self.connection = None 61 self.queries = [] 62 63 def cursor(self): 64 from django.conf import settings 51 from django.db.backends import OldLayoutBaseDatabaseWrapper 52 53 class DatabaseWrapper(OldLayoutBaseDatabaseWrapper): 54 55 def _cursor(self, settings): 65 56 if self.connection is None: 66 57 if settings.DATABASE_NAME == '' or settings.DATABASE_USER == '': 67 58 from django.core.exceptions import ImproperlyConfigured … … 71 62 # TODO: Handle DATABASE_PORT. 72 63 conn_string = "PROVIDER=SQLOLEDB;DATA SOURCE=%s;UID=%s;PWD=%s;DATABASE=%s" % (settings.DATABASE_HOST, settings.DATABASE_USER, settings.DATABASE_PASSWORD, settings.DATABASE_NAME) 73 64 self.connection = Database.connect(conn_string) 74 cursor = self.connection.cursor() 75 if settings.DEBUG: 76 return util.CursorDebugWrapper(cursor, self) 77 return cursor 78 79 def _commit(self): 80 if self.connection is not None: 81 return self.connection.commit() 82 83 def _rollback(self): 84 if self.connection is not None: 85 return self.connection.rollback() 86 87 def close(self): 88 if self.connection is not None: 89 self.connection.close() 90 self.connection = None 65 return self.connection.cursor() 66 91 67 92 68 allows_group_by_ordinal = True 93 69 allows_unique_and_pk = True -
django/db/backends/mysql/base.py
=== modified file 'django/db/backends/mysql/base.py'
53 53 # standard util.CursorDebugWrapper can be used. Also, using sql_mode 54 54 # TRADITIONAL will automatically cause most warnings to be treated as errors. 55 55 56 try: 57 # Only exists in Python 2.4+ 58 from threading import local 59 except ImportError:60 # Import copy of _thread_local.py from Python 2.4 61 from django.utils._threading_local import local62 63 class DatabaseWrapper(local): 56 57 from django.db.backends import OldLayoutBaseDatabaseWrapper 58 59 class DatabaseWrapper(OldLayoutBaseDatabaseWrapper): 60 61 DatabaseError = Database.DatabaseError 62 IntegrityError = Database.IntegrityError 63 64 64 def __init__(self, **kwargs): 65 self.connection = None 66 self.queries = [] 65 super(DatabaseWrapper, self).__init__(**kwargs) 67 66 self.server_version = None 68 self.options = kwargs69 67 70 68 def _valid_connection(self): 71 69 if self.connection is not None: … … 77 75 self.connection = None 78 76 return False 79 77 80 def cursor(self): 81 from django.conf import settings 78 def _cursor(self, settings): 82 79 from warnings import filterwarnings 83 80 if not self._valid_connection(): 84 81 kwargs = { … … 100 97 kwargs['port'] = int(settings.DATABASE_PORT) 101 98 kwargs.update(self.options) 102 99 self.connection = Database.connect(**kwargs) 103 cursor = self.connection.cursor() 104 else: 105 cursor = self.connection.cursor() 100 cursor = self.connection.cursor() 106 101 if settings.DEBUG: 107 102 filterwarnings("error", category=Database.Warning) 108 return util.CursorDebugWrapper(cursor, self)109 103 return cursor 110 104 111 def _commit(self):112 if self.connection is not None:113 self.connection.commit()114 115 105 def _rollback(self): 116 if self.connection is not None: 117 try: 118 self.connection.rollback() 119 except Database.NotSupportedError: 120 pass 121 122 def close(self): 123 if self.connection is not None: 124 self.connection.close() 125 self.connection = None 106 try: 107 OldLayoutBaseDatabaseWrapper._rollback(self) 108 except Database.NotSupportedError: 109 pass 126 110 127 111 def get_server_version(self): 128 112 if not self.server_version: -
django/db/backends/mysql_old/base.py
=== modified file 'django/db/backends/mysql_old/base.py'
63 63 else: 64 64 return getattr(self.cursor, attr) 65 65 66 try: 67 # Only exists in Python 2.4+ 68 from threading import local 69 except ImportError: 70 # Import copy of _thread_local.py from Python 2.4 71 from django.utils._threading_local import local 66 from django.db.backends import OldLayoutBaseDatabaseWrapper 72 67 73 class DatabaseWrapper( local):68 class DatabaseWrapper(OldLayoutBaseDatabaseWrapper): 74 69 def __init__(self, **kwargs): 75 self.connection = None 76 self.queries = [] 70 super(DatabaseWrapper, self).__init__(**kwargs) 77 71 self.server_version = None 78 self.options = kwargs79 72 80 73 def _valid_connection(self): 81 74 if self.connection is not None: … … 87 80 self.connection = None 88 81 return False 89 82 90 def cursor(self): 91 from django.conf import settings 83 def _cursor(self, settings): 92 84 if not self._valid_connection(): 93 85 kwargs = { 94 86 # Note: use_unicode intentonally not set to work around some … … 119 111 self.connection.set_character_set('utf8') 120 112 else: 121 113 cursor = self.connection.cursor() 122 if settings.DEBUG: 123 return util.CursorDebugWrapper(MysqlDebugWrapper(cursor), self) 114 124 115 return cursor 125 116 126 def _commit(self): 127 if self.connection is not None: 128 self.connection.commit() 117 def make_debug_cursor(self, cursor): 118 return OldLayoutBaseDatabaseWrapper.make_debug_cursor(self, MysqlDebugWrapper(cursor)) 129 119 130 120 def _rollback(self): 131 if self.connection is not None: 132 try: 133 self.connection.rollback() 134 except Database.NotSupportedError: 135 pass 136 137 def close(self): 138 if self.connection is not None: 139 self.connection.close() 140 self.connection = None 121 try: 122 OldLayoutBaseDatabaseWrapper._rollback(self) 123 except Database.NotSupportedError: 124 pass 141 125 142 126 def get_server_version(self): 143 127 if not self.server_version: -
django/db/backends/oracle/base.py
=== modified file 'django/db/backends/oracle/base.py'
23 23 DatabaseError = Database.Error 24 24 IntegrityError = Database.IntegrityError 25 25 26 try: 27 # Only exists in Python 2.4+ 28 from threading import local 29 except ImportError: 30 # Import copy of _thread_local.py from Python 2.4 31 from django.utils._threading_local import local 26 from django.db.backends import OldLayoutBaseDatabaseWrapper 32 27 33 class DatabaseWrapper(local): 34 def __init__(self, **kwargs): 35 self.connection = None 36 self.queries = [] 37 self.options = kwargs 28 class DatabaseWrapper(OldLayoutBaseDatabaseWrapper): 38 29 39 30 def _valid_connection(self): 40 31 return self.connection is not None 41 32 42 def cursor(self):33 def _cursor(self, settings): 43 34 if not self._valid_connection(): 44 35 if len(settings.DATABASE_HOST.strip()) == 0: 45 36 settings.DATABASE_HOST = 'localhost' … … 55 46 # Set oracle date to ansi date format. 56 47 cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'") 57 48 cursor.execute("ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'") 58 if settings.DEBUG:59 return util.CursorDebugWrapper(cursor, self)60 49 return cursor 61 50 62 def _commit(self):63 if self.connection is not None:64 return self.connection.commit()65 66 def _rollback(self):67 if self.connection is not None:68 return self.connection.rollback()69 70 def close(self):71 if self.connection is not None:72 self.connection.close()73 self.connection = None74 51 75 52 allows_group_by_ordinal = False 76 53 allows_unique_and_pk = False # Suppress UNIQUE/PK for Oracle (ORA-02259) -
django/db/backends/postgresql/base.py
=== modified file 'django/db/backends/postgresql/base.py'
15 15 DatabaseError = Database.DatabaseError 16 16 IntegrityError = Database.IntegrityError 17 17 18 try: 19 # Only exists in Python 2.4+ 20 from threading import local 21 except ImportError: 22 # Import copy of _thread_local.py from Python 2.4 23 from django.utils._threading_local import local 18 from django.db.backends import OldLayoutBaseDatabaseWrapper 24 19 25 20 class UnicodeCursorWrapper(object): 26 21 """ … … 64 59 65 60 postgres_version = None 66 61 67 class DatabaseWrapper(local): 68 def __init__(self, **kwargs): 69 self.connection = None 70 self.queries = [] 71 self.options = kwargs 62 class DatabaseWrapper(OldLayoutBaseDatabaseWrapper): 72 63 73 def cursor(self): 74 from django.conf import settings 64 def _cursor(self, settings): 75 65 set_tz = False 76 66 if self.connection is None: 77 67 set_tz = True … … 98 88 if not postgres_version: 99 89 cursor.execute("SELECT version()") 100 90 postgres_version = [int(val) for val in cursor.fetchone()[0].split()[1].split('.')] 101 if settings.DEBUG:102 return util.CursorDebugWrapper(cursor, self)103 91 return cursor 104 92 105 def _commit(self):106 if self.connection is not None:107 return self.connection.commit()108 109 def _rollback(self):110 if self.connection is not None:111 return self.connection.rollback()112 113 def close(self):114 if self.connection is not None:115 self.connection.close()116 self.connection = None117 118 93 allows_group_by_ordinal = True 119 94 allows_unique_and_pk = True 120 95 autoindexes_primary_keys = True -
django/db/backends/postgresql_psycopg2/base.py
=== modified file 'django/db/backends/postgresql_psycopg2/base.py'
5 5 """ 6 6 7 7 from django.db.backends import util 8 from django.db.backends import OldLayoutBaseDatabaseWrapper 9 8 10 try: 9 11 import psycopg2 as Database 10 12 import psycopg2.extensions … … 15 17 DatabaseError = Database.DatabaseError 16 18 IntegrityError = Database.IntegrityError 17 19 18 try:19 # Only exists in Python 2.4+20 from threading import local21 except ImportError:22 # Import copy of _thread_local.py from Python 2.423 from django.utils._threading_local import local24 25 20 psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) 26 21 27 22 postgres_version = None 28 23 29 class DatabaseWrapper(local): 30 def __init__(self, **kwargs): 31 self.connection = None 32 self.queries = [] 33 self.options = kwargs 24 class DatabaseWrapper(OldLayoutBaseDatabaseWrapper): 34 25 35 def cursor(self): 36 from django.conf import settings 26 def _cursor(self, settings): 37 27 set_tz = False 38 28 if self.connection is None: 39 29 set_tz = True … … 60 50 if not postgres_version: 61 51 cursor.execute("SELECT version()") 62 52 postgres_version = [int(val) for val in cursor.fetchone()[0].split()[1].split('.')] 63 if settings.DEBUG:64 return util.CursorDebugWrapper(cursor, self)65 53 return cursor 66 54 67 def _commit(self):68 if self.connection is not None:69 return self.connection.commit()70 71 def _rollback(self):72 if self.connection is not None:73 return self.connection.rollback()74 75 def close(self):76 if self.connection is not None:77 self.connection.close()78 self.connection = None79 55 80 56 allows_group_by_ordinal = True 81 57 allows_unique_and_pk = True -
django/db/backends/sqlite3/base.py
=== modified file 'django/db/backends/sqlite3/base.py'
34 34 Database.register_converter("decimal", util.typecast_decimal) 35 35 Database.register_adapter(decimal.Decimal, util.rev_typecast_decimal) 36 36 37 try: 38 # Only exists in Python 2.4+ 39 from threading import local 40 except ImportError: 41 # Import copy of _thread_local.py from Python 2.4 42 from django.utils._threading_local import local 43 44 class DatabaseWrapper(local): 45 def __init__(self, **kwargs): 46 self.connection = None 47 self.queries = [] 48 self.options = kwargs 49 50 def cursor(self): 51 from django.conf import settings 37 from django.db.backends import OldLayoutBaseDatabaseWrapper 38 39 class DatabaseWrapper(OldLayoutBaseDatabaseWrapper): 40 41 def _cursor(self, settings): 52 42 if self.connection is None: 53 43 kwargs = { 54 44 'database': settings.DATABASE_NAME, … … 60 50 self.connection.create_function("django_extract", 2, _sqlite_extract) 61 51 self.connection.create_function("django_date_trunc", 2, _sqlite_date_trunc) 62 52 self.connection.create_function("regexp", 2, _sqlite_regexp) 63 cursor = self.connection.cursor(factory=SQLiteCursorWrapper) 64 if settings.DEBUG: 65 return util.CursorDebugWrapper(cursor, self) 66 else: 67 return cursor 68 69 def _commit(self): 70 if self.connection is not None: 71 self.connection.commit() 72 73 def _rollback(self): 74 if self.connection is not None: 75 self.connection.rollback() 53 return self.connection.cursor(factory=SQLiteCursorWrapper) 76 54 77 55 def close(self): 78 56 from django.conf import settings 79 57 # If database is in memory, closing the connection destroys the 80 58 # database. To prevent accidental data loss, ignore close requests on 81 59 # an in-memory db. 82 if se lf.connection is not None and settings.DATABASE_NAME != ":memory:":83 self.connection.close()84 self.connection = None 60 if settings.DATABASE_NAME != ':memory:': 61 OldLayoutBaseDatabaseWrapper.close(self) 62 85 63 86 64 class SQLiteCursorWrapper(Database.Cursor): 87 65 """ -
django/db/models/base.py
=== modified file 'django/db/models/base.py'
6 6 from django.db.models.fields.related import OneToOneRel, ManyToOneRel 7 7 from django.db.models.query import delete_objects 8 8 from django.db.models.options import Options, AdminOptions 9 from django.db import connection, backend,transaction9 from django.db import connection, transaction 10 10 from django.db.models import signals 11 11 from django.db.models.loading import register_models, get_model 12 12 from django.dispatch import dispatcher … … 207 207 non_pks = [f for f in self._meta.fields if not f.primary_key] 208 208 cursor = connection.cursor() 209 209 210 ops = connection.ops 211 quote_name = ops.quote_name 210 212 # First, try an UPDATE. If that doesn't update anything, do an INSERT. 211 213 pk_val = self._get_pk_val() 212 214 pk_set = bool(pk_val) … … 214 216 if pk_set: 215 217 # Determine whether a record with the primary key already exists. 216 218 cursor.execute("SELECT COUNT(*) FROM %s WHERE %s=%%s" % \ 217 ( backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column)),219 (quote_name(self._meta.db_table), quote_name(self._meta.pk.column)), 218 220 self._meta.pk.get_db_prep_lookup('exact', pk_val)) 219 221 # If it does already exist, do an UPDATE. 220 222 if cursor.fetchone()[0] > 0: 221 223 db_values = [f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, False)) for f in non_pks] 222 224 if db_values: 223 225 cursor.execute("UPDATE %s SET %s WHERE %s=%%s" % \ 224 ( backend.quote_name(self._meta.db_table),225 ','.join(['%s=%%s' % backend.quote_name(f.column) for f in non_pks]),226 backend.quote_name(self._meta.pk.column)),226 (quote_name(self._meta.db_table), 227 ','.join(['%s=%%s' % quote_name(f.column) for f in non_pks]), 228 quote_name(self._meta.pk.column)), 227 229 db_values + self._meta.pk.get_db_prep_lookup('exact', pk_val)) 228 230 else: 229 231 record_exists = False 230 232 if not pk_set or not record_exists: 231 field_names = [ backend.quote_name(f.column) for f in self._meta.fields if not isinstance(f, AutoField)]233 field_names = [quote_name(f.column) for f in self._meta.fields if not isinstance(f, AutoField)] 232 234 db_values = [f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True)) for f in self._meta.fields if not isinstance(f, AutoField)] 233 235 # If the PK has been manually set, respect that. 234 236 if pk_set: … … 236 238 db_values += [f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True)) for f in self._meta.fields if isinstance(f, AutoField)] 237 239 placeholders = ['%s'] * len(field_names) 238 240 if self._meta.order_with_respect_to: 239 field_names.append( backend.quote_name('_order'))241 field_names.append(quote_name('_order')) 240 242 # TODO: This assumes the database supports subqueries. 241 243 placeholders.append('(SELECT COUNT(*) FROM %s WHERE %s = %%s)' % \ 242 ( backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.order_with_respect_to.column)))244 (quote_name(self._meta.db_table), quote_name(self._meta.order_with_respect_to.column))) 243 245 db_values.append(getattr(self, self._meta.order_with_respect_to.attname)) 244 246 if db_values: 245 247 cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % \ 246 ( backend.quote_name(self._meta.db_table), ','.join(field_names),248 (quote_name(self._meta.db_table), ','.join(field_names), 247 249 ','.join(placeholders)), db_values) 248 250 else: 249 251 # Create a new record with defaults for everything. 250 252 cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % 251 ( backend.quote_name(self._meta.db_table),252 backend.quote_name(self._meta.pk.column),253 backend.get_pk_default_value()))253 (quote_name(self._meta.db_table), 254 quote_name(self._meta.pk.column), 255 ops.get_pk_default_value())) 254 256 if self._meta.has_auto_field and not pk_set: 255 setattr(self, self._meta.pk.attname, backend.get_last_insert_id(cursor, self._meta.db_table, self._meta.pk.column))257 setattr(self, self._meta.pk.attname, ops.get_last_insert_id(cursor, self._meta.db_table, self._meta.pk.column)) 256 258 transaction.commit_unless_managed() 257 259 258 260 # Run any post-save hooks. … … 326 328 def _get_next_or_previous_by_FIELD(self, field, is_next, **kwargs): 327 329 op = is_next and '>' or '<' 328 330 where = '(%s %s %%s OR (%s = %%s AND %s.%s %s %%s))' % \ 329 ( backend.quote_name(field.column), op, backend.quote_name(field.column),330 backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column), op)331 (connection.ops.quote_name(field.column), op, connection.ops.quote_name(field.column), 332 connection.ops.quote_name(self._meta.db_table), connection.ops.quote_name(self._meta.pk.column), op) 331 333 param = smart_str(getattr(self, field.attname)) 332 334 q = self.__class__._default_manager.filter(**kwargs).order_by((not is_next and '-' or '') + field.name, (not is_next and '-' or '') + self._meta.pk.name) 333 335 q._where.append(where) … … 343 345 op = is_next and '>' or '<' 344 346 order_field = self._meta.order_with_respect_to 345 347 where = ['%s %s (SELECT %s FROM %s WHERE %s=%%s)' % \ 346 ( backend.quote_name('_order'), op, backend.quote_name('_order'),347 backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column)),348 '%s=%%s' % backend.quote_name(order_field.column)]348 (connection.ops.quote_name('_order'), op, connection.ops.quote_name('_order'), 349 connection.ops.quote_name(self._meta.db_table), connection.ops.quote_name(self._meta.pk.column)), 350 '%s=%%s' % connection.ops.quote_name(order_field.column)] 349 351 params = [self._get_pk_val(), getattr(self, order_field.attname)] 350 352 obj = self._default_manager.order_by('_order').extra(where=where, params=params)[:1].get() 351 353 setattr(self, cachename, obj) … … 430 432 cursor = connection.cursor() 431 433 # Example: "UPDATE poll_choices SET _order = %s WHERE poll_id = %s AND id = %s" 432 434 sql = "UPDATE %s SET %s = %%s WHERE %s = %%s AND %s = %%s" % \ 433 ( backend.quote_name(ordered_obj._meta.db_table), backend.quote_name('_order'),434 backend.quote_name(ordered_obj._meta.order_with_respect_to.column),435 backend.quote_name(ordered_obj._meta.pk.column))435 (connection.ops.quote_name(ordered_obj._meta.db_table), connection.ops.quote_name('_order'), 436 connection.ops.quote_name(ordered_obj._meta.order_with_respect_to.column), 437 connection.ops.quote_name(ordered_obj._meta.pk.column)) 436 438 rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name) 437 439 cursor.executemany(sql, [(i, rel_val, j) for i, j in enumerate(id_list)]) 438 440 transaction.commit_unless_managed() … … 441 443 cursor = connection.cursor() 442 444 # Example: "SELECT id FROM poll_choices WHERE poll_id = %s ORDER BY _order" 443 445 sql = "SELECT %s FROM %s WHERE %s = %%s ORDER BY %s" % \ 444 ( backend.quote_name(ordered_obj._meta.pk.column),445 backend.quote_name(ordered_obj._meta.db_table),446 backend.quote_name(ordered_obj._meta.order_with_respect_to.column),447 backend.quote_name('_order'))446 (connection.ops.quote_name(ordered_obj._meta.pk.column), 447 connection.ops.quote_name(ordered_obj._meta.db_table), 448 connection.ops.quote_name(ordered_obj._meta.order_with_respect_to.column), 449 connection.ops.quote_name('_order')) 448 450 rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name) 449 451 cursor.execute(sql, [rel_val]) 450 452 return [r[0] for r in cursor.fetchall()] -
django/db/models/fields/related.py
=== modified file 'django/db/models/fields/related.py'
1 from django.db import backend, transaction1 from django.db import connection, transaction 2 2 from django.db.models import signals, get_model 3 3 from django.db.models.fields import AutoField, Field, IntegerField, PositiveIntegerField, PositiveSmallIntegerField, get_ul_class 4 4 from django.db.models.related import RelatedObject … … 400 400 superclass = rel_model._default_manager.__class__ 401 401 RelatedManager = create_many_related_manager(superclass) 402 402 403 qn = backend.quote_name403 qn = connection.ops.quote_name 404 404 manager = RelatedManager( 405 405 model=rel_model, 406 406 core_filters={'%s__pk' % self.related.field.name: instance._get_pk_val()}, … … 441 441 superclass = rel_model._default_manager.__class__ 442 442 RelatedManager = create_many_related_manager(superclass) 443 443 444 qn = backend.quote_name444 qn = connection.ops.quote_name 445 445 manager = RelatedManager( 446 446 model=rel_model, 447 447 core_filters={'%s__pk' % self.field.related_query_name(): instance._get_pk_val()}, -
django/db/models/options.py
=== modified file 'django/db/models/options.py'
63 63 del self.meta 64 64 65 65 def _prepare(self, model): 66 from django.db import backend66 from django.db import connection 67 67 from django.db.backends.util import truncate_name 68 68 if self.order_with_respect_to: 69 69 self.order_with_respect_to = self.get_field(self.order_with_respect_to) … … 80 80 if not self.db_table: 81 81 self.db_table = "%s_%s" % (self.app_label, self.module_name) 82 82 self.db_table = truncate_name(self.db_table, 83 backend.get_max_name_length())83 connection.ops.get_max_name_length()) 84 84 85 85 def add_field(self, field): 86 86 # Insert the given field in the order in which it was created, using -
django/db/models/query.py
=== modified file 'django/db/models/query.py'
64 64 return f 65 65 66 66 def orderlist2sql(order_list, opts, prefix=''): 67 quote_name = connection.ops.quote_name 68 get_rand_sql = connection.ops.get_random_function_sql 67 69 if prefix.endswith('.'): 68 prefix = backend.quote_name(prefix[:-1]) + '.'70 prefix = quote_name(prefix[:-1]) + '.' 69 71 output = [] 70 72 for f in handle_legacy_orderlist(order_list): 71 73 if f.startswith('-'): 72 output.append('%s%s DESC' % (prefix, backend.quote_name(orderfield2column(f[1:], opts))))74 output.append('%s%s DESC' % (prefix, quote_name(orderfield2column(f[1:], opts)))) 73 75 elif f == '?': 74 output.append( backend.get_random_function_sql())76 output.append(get_rand_sql()) 75 77 else: 76 output.append('%s%s ASC' % (prefix, backend.quote_name(orderfield2column(f, opts))))78 output.append('%s%s ASC' % (prefix, quote_name(orderfield2column(f, opts)))) 77 79 return ', '.join(output) 78 80 79 81 def quote_only_if_word(word): 80 82 if re.search('\W', word): # Don't quote if there are spaces or non-word chars. 81 83 return word 82 84 else: 83 return backend.quote_name(word)85 return connection.ops.quote_name(word) 84 86 85 87 class _QuerySet(object): 86 88 "Represents a lazy database lookup for a set of objects" … … 235 237 236 238 cursor = connection.cursor() 237 239 if self._distinct: 238 id_col = "%s.%s" % ( backend.quote_name(self.model._meta.db_table),239 backend.quote_name(self.model._meta.pk.column))240 id_col = "%s.%s" % (connection.ops.quote_name(self.model._meta.db_table), 241 connection.ops.quote_name(self.model._meta.pk.column)) 240 242 cursor.execute("SELECT COUNT(DISTINCT(%s))" % id_col + sql, params) 241 243 else: 242 244 cursor.execute("SELECT COUNT(*)" + sql, params) … … 312 314 if id_list == []: 313 315 return {} 314 316 qs = self._clone() 315 qs._where.append("%s.%s IN (%s)" % (backend.quote_name(self.model._meta.db_table), backend.quote_name(self.model._meta.pk.column), ",".join(['%s'] * len(id_list)))) 317 qs._where.append("%s.%s IN (%s)" % (connection.ops.quote_name(self.model._meta.db_table), 318 connection.ops.quote_name(self.model._meta.pk.column), ",".join(['%s'] * len(id_list)))) 316 319 qs._params.extend(id_list) 317 320 return dict([(obj._get_pk_val(), obj) for obj in qs.iterator()]) 318 321 … … 483 486 def _get_sql_clause(self): 484 487 opts = self.model._meta 485 488 489 quote_name = connection.ops.quote_name 486 490 # Construct the fundamental parts of the query: SELECT X FROM Y WHERE Z. 487 select = ["%s.%s" % ( backend.quote_name(opts.db_table), backend.quote_name(f.column)) for f in opts.fields]491 select = ["%s.%s" % (quote_name(opts.db_table), quote_name(f.column)) for f in opts.fields] 488 492 tables = [quote_only_if_word(t) for t in self._tables] 489 493 joins = SortedDict() 490 494 where = self._where[:] … … 505 509 506 510 # Add any additional SELECTs. 507 511 if self._select: 508 select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), backend.quote_name(s[0])) for s in self._select.items()])512 select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), quote_name(s[0])) for s in self._select.items()]) 509 513 510 514 # Start composing the body of the SQL statement. 511 sql = [" FROM", backend.quote_name(opts.db_table)]515 sql = [" FROM", quote_name(opts.db_table)] 512 516 513 517 # Compose the join dictionary into SQL describing the joins. 514 518 if joins: … … 531 535 ordering_to_use = opts.ordering 532 536 for f in handle_legacy_orderlist(ordering_to_use): 533 537 if f == '?': # Special case. 534 order_by.append( backend.get_random_function_sql())538 order_by.append(connection.ops.get_random_function_sql()) 535 539 else: 536 540 if f.startswith('-'): 537 541 col_name = f[1:] … … 541 545 order = "ASC" 542 546 if "." in col_name: 543 547 table_prefix, col_name = col_name.split('.', 1) 544 table_prefix = backend.quote_name(table_prefix) + '.'548 table_prefix = quote_name(table_prefix) + '.' 545 549 else: 546 550 # Use the database table as a column prefix if it wasn't given, 547 551 # and if the requested column isn't a custom SELECT. 548 552 if "." not in col_name and col_name not in (self._select or ()): 549 table_prefix = backend.quote_name(opts.db_table) + '.'553 table_prefix = quote_name(opts.db_table) + '.' 550 554 else: 551 555 table_prefix = '' 552 order_by.append('%s%s %s' % (table_prefix, backend.quote_name(orderfield2column(col_name, opts)), order))556 order_by.append('%s%s %s' % (table_prefix, quote_name(orderfield2column(col_name, opts)), order)) 553 557 if order_by: 554 558 sql.append("ORDER BY " + ", ".join(order_by)) 555 559 556 560 # LIMIT and OFFSET clauses 557 561 if self._limit is not None: 558 sql.append("%s " % backend.get_limit_offset_sql(self._limit, self._offset))562 sql.append("%s " % connection.ops.get_limit_offset_sql(self._limit, self._offset)) 559 563 else: 560 564 assert self._offset is None, "'offset' is not allowed without 'limit'" 561 565 562 566 return select, " ".join(sql), params 563 567 564 568 # Use the backend's QuerySet class if it defines one, otherwise use _QuerySet. 565 if hasattr( backend, 'get_query_set_class'):566 QuerySet = backend.get_query_set_class(_QuerySet)569 if hasattr(connection.ops, 'get_query_set_class'): 570 QuerySet = connection.ops.get_query_set_class(_QuerySet) 567 571 else: 568 572 QuerySet = _QuerySet 569 573 … … 605 609 field_names = [f.attname for f in fields] 606 610 607 611 columns = [f.column for f in fields] 608 select = ['%s.%s' % ( backend.quote_name(self.model._meta.db_table), backend.quote_name(c)) for c in columns]612 select = ['%s.%s' % (connection.ops.quote_name(self.model._meta.db_table), connection.ops.quote_name(c)) for c in columns] 609 613 if extra_select: 610 select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), backend.quote_name(s[0])) for s in extra_select])614 select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), connection.ops.quote_name(s[0])) for s in extra_select]) 611 615 field_names.extend([f[0] for f in extra_select]) 612 616 613 617 cursor = connection.cursor() … … 635 639 self._order_by = () # Clear this because it'll mess things up otherwise. 636 640 if self._field.null: 637 641 self._where.append('%s.%s IS NOT NULL' % \ 638 ( backend.quote_name(self.model._meta.db_table), backend.quote_name(self._field.column)))642 (connection.ops.quote_name(self.model._meta.db_table), connection.ops.quote_name(self._field.column))) 639 643 try: 640 644 select, sql, params = self._get_sql_clause() 641 645 except EmptyResultSet: 642 646 raise StopIteration 643 647 644 table_name = backend.quote_name(self.model._meta.db_table)645 field_name = backend.quote_name(self._field.column)648 table_name = connection.ops.quote_name(self.model._meta.db_table) 649 field_name = connection.ops.quote_name(self._field.column) 646 650 647 if backend.allows_group_by_ordinal:651 if connection.capabilities.allows_group_by_ordinal: 648 652 group_by = '1' 649 653 else: 650 group_by = backend.get_date_trunc_sql(self._kind,654 group_by = connection.ops.get_date_trunc_sql(self._kind, 651 655 '%s.%s' % (table_name, field_name)) 652 656 653 657 sql = 'SELECT %s %s GROUP BY %s ORDER BY 1 %s' % \ 654 ( backend.get_date_trunc_sql(self._kind, '%s.%s' % (backend.quote_name(self.model._meta.db_table),655 backend.quote_name(self._field.column))), sql, group_by, self._order)658 (connection.ops.get_date_trunc_sql(self._kind, '%s.%s' % (connection.ops.quote_name(self.model._meta.db_table), 659 connection.ops.quote_name(self._field.column))), sql, group_by, self._order) 656 660 cursor = connection.cursor() 657 661 cursor.execute(sql, params) 658 662 659 663 has_resolve_columns = hasattr(self, 'resolve_columns') 660 needs_datetime_string_cast = backend.needs_datetime_string_cast664 needs_datetime_string_cast = connection.capabilities.needs_datetime_string_cast 661 665 dates = [] 662 666 # It would be better to use self._field here instead of DateTimeField(), 663 667 # but in Oracle that will result in a list of datetime.date instead of … … 779 783 780 784 def get_where_clause(lookup_type, table_prefix, field_name, value): 781 785 if table_prefix.endswith('.'): 782 table_prefix = backend.quote_name(table_prefix[:-1])+'.'783 field_name = backend.quote_name(field_name)784 if type(value) == datetime.datetime and backend.get_datetime_cast_sql():785 cast_sql = backend.get_datetime_cast_sql()786 table_prefix = connection.ops.quote_name(table_prefix[:-1])+'.' 787 field_name = connection.ops.quote_name(field_name) 788 if type(value) == datetime.datetime and connection.ops.get_datetime_cast_sql(): 789 cast_sql = connection.ops.get_datetime_cast_sql() 786 790 else: 787 791 cast_sql = '%s' 788 if lookup_type in ('iexact', 'icontains', 'istartswith', 'iendswith') and backend.needs_upper_for_iops:792 if lookup_type in ('iexact', 'icontains', 'istartswith', 'iendswith') and connection.capabilities.needs_upper_for_iops: 789 793 format = 'UPPER(%s%s) %s' 790 794 else: 791 795 format = '%s%s %s' 792 796 try: 793 797 return format % (table_prefix, field_name, 794 backend.OPERATOR_MAPPING[lookup_type] % cast_sql)798 connection.orm_map[lookup_type] % cast_sql) 795 799 except KeyError: 796 800 pass 797 801 if lookup_type == 'in': … … 803 807 elif lookup_type in ('range', 'year'): 804 808 return '%s%s BETWEEN %%s AND %%s' % (table_prefix, field_name) 805 809 elif lookup_type in ('month', 'day'): 806 return "%s = %%s" % backend.get_date_extract_sql(lookup_type, table_prefix + field_name)810 return "%s = %%s" % connection.ops.get_date_extract_sql(lookup_type, table_prefix + field_name) 807 811 elif lookup_type == 'isnull': 808 812 return "%s%s IS %sNULL" % (table_prefix, field_name, (not value and 'NOT ' or '')) 809 813 elif lookup_type == 'search': 810 return backend.get_fulltext_search_sql(table_prefix + field_name)814 return connection.ops.get_fulltext_search_sql(table_prefix + field_name) 811 815 elif lookup_type in ('regex', 'iregex'): 812 816 if settings.DATABASE_ENGINE == 'oracle': 813 817 if lookup_type == 'regex': … … 846 850 if max_depth and cur_depth > max_depth: 847 851 return None 848 852 849 qn = backend.quote_name853 qn = connection.ops.quote_name 850 854 for f in opts.fields: 851 855 if f.rel and not f.null: 852 856 db_table = f.rel.to._meta.db_table … … 944 948 return choices 945 949 946 950 def lookup_inner(path, lookup_type, value, opts, table, column): 947 qn = backend.quote_name951 qn = connection.ops.quote_name 948 952 joins, where, params = SortedDict(), [], [] 949 953 current_opts = opts 950 954 current_table = table … … 1108 1112 1109 1113 def delete_objects(seen_objs): 1110 1114 "Iterate through a list of seen classes, and remove any instances that are referred to" 1111 qn = backend.quote_name1115 qn = connection.ops.quote_name 1112 1116 ordered_classes = seen_objs.keys() 1113 1117 ordered_classes.reverse() 1114 1118 -
django/test/utils.py
=== modified file 'django/test/utils.py'
119 119 cursor = connection.cursor() 120 120 _set_autocommit(connection) 121 121 try: 122 cursor.execute("CREATE DATABASE %s %s" % ( backend.quote_name(TEST_DATABASE_NAME), suffix))122 cursor.execute("CREATE DATABASE %s %s" % (connection.ops.quote_name(TEST_DATABASE_NAME), suffix)) 123 123 except Exception, e: 124 124 sys.stderr.write("Got an error creating the test database: %s\n" % e) 125 125 if not autoclobber: … … 128 128 try: 129 129 if verbosity >= 1: 130 130 print "Destroying old test database..." 131 cursor.execute("DROP DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME))131 cursor.execute("DROP DATABASE %s" % connection.ops.quote_name(TEST_DATABASE_NAME)) 132 132 if verbosity >= 1: 133 133 print "Creating test database..." 134 cursor.execute("CREATE DATABASE %s %s" % ( backend.quote_name(TEST_DATABASE_NAME), suffix))134 cursor.execute("CREATE DATABASE %s %s" % (connection.ops.quote_name(TEST_DATABASE_NAME), suffix)) 135 135 except Exception, e: 136 136 sys.stderr.write("Got an error recreating the test database: %s\n" % e) 137 137 sys.exit(2) … … 173 173 cursor = connection.cursor() 174 174 _set_autocommit(connection) 175 175 time.sleep(1) # To avoid "database is being accessed by other users" errors. 176 cursor.execute("DROP DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME))176 cursor.execute("DROP DATABASE %s" % connection.ops.quote_name(TEST_DATABASE_NAME)) 177 177 connection.close()