Ticket #12308: 12308-with-mysql-support-dont-use.patch
File 12308-with-mysql-support-dont-use.patch, 26.8 KB (added by , 13 years ago) |
---|
-
docs/index.txt
66 66 :doc:`Transactions <topics/db/transactions>` | 67 67 :doc:`Aggregation <topics/db/aggregation>` | 68 68 :doc:`Custom fields <howto/custom-model-fields>` | 69 :doc:`Multiple databases <topics/db/multi-db>` 69 :doc:`Multiple databases <topics/db/multi-db>` | 70 :doc:`Tablespaces <topics/db/tablespaces>` 70 71 71 72 * **Other:** 72 73 :doc:`Supported databases <ref/databases>` | -
docs/howto/custom-model-fields.txt
218 218 * :attr:`~django.db.models.Field.choices` 219 219 * :attr:`~django.db.models.Field.help_text` 220 220 * :attr:`~django.db.models.Field.db_column` 221 * :attr:`~django.db.models.Field.db_tablespace`: Currently only used with222 the Oracle backend and only for index creation. You can usually ignore223 this option.221 * :attr:`~django.db.models.Field.db_tablespace`: Only for index creation, 222 if the backend supports :doc:`tablespaces </topics/db/tablespaces>` for 223 indexes. You can usually ignore this option. 224 224 * :attr:`~django.db.models.Field.auto_created`: True if the field was 225 225 automatically created, as for the `OneToOneField` used by model 226 226 inheritance. For advanced use only. -
docs/topics/db/tablespaces.txt
1 =========== 2 Tablespaces 3 =========== 4 5 A common paradigm for optimizing performance in database systems is the use of 6 `tablespaces`_ to organize disk layout. 7 8 .. _`tablespaces`: http://en.wikipedia.org/wiki/Tablespace 9 10 .. warning:: 11 Django does not create the tablespaces for you. Please refer to your 12 database engine's documentation for details on creating and managing 13 tablespaces. 14 15 16 Declaring tablespaces for tables 17 -------------------------------- 18 19 A tablespace can be specified for the table generated by a model by supplying 20 the :attr:`~django.db.models.Options.db_tablespace` option inside the model's 21 ``class Meta``. This option also affects tables automatically created for 22 :class:`~django.db.models.ManyToManyField`\ s in the model. 23 24 You can use the :setting:`DEFAULT_TABLESPACE` setting to specify a default value 25 for :attr:`~django.db.models.Options.db_tablespace`. These is useful for setting 26 a tablespace for the built-in Django apps and other applications whose code you 27 cannot control. 28 29 Declaring tablespaces for indexes 30 --------------------------------- 31 32 You can pass the :attr:`~django.db.models.Field.db_tablespace` option to a 33 ``Field`` constructor to specify an alternate tablespace for the ``Field``'s 34 column index. If no index would be created for the column, the option is 35 ignored. 36 37 You can use the :setting:`DEFAULT_INDEX_TABLESPACE` setting to specify 38 a default value for :attr:`~django.db.models.Field.db_tablespace`. 39 40 If :attr:`~django.db.models.Field.db_tablespace` isn't specified and you didn't 41 set :setting:`DEFAULT_INDEX_TABLESPACE`, the index is created in the same 42 tablespace as the tables. 43 44 An example 45 ---------- 46 47 .. code-block:: python 48 49 class TablespaceExample(models.Model): 50 name = models.CharField(max_length=30, db_index=True, db_tablespace="indexes") 51 data = models.CharField(max_length=255, db_index=True) 52 edges = models.ManyToManyField(to="self", db_tablespace="indexes") 53 54 class Meta: 55 db_tablespace = "tables" 56 57 In this example, the tables generated by the ``TablespaceExample`` model (i.e. 58 the model table and the many-to-many table) would be stored in the ``tables`` 59 tablespace. The index for the name field and the indexes on the many-to-many 60 table would be stored in the ``indexes`` tablespace. The ``data`` field would 61 also generate an index, but no tablespace for it is specified, so it would be 62 stored in the model tablespace ``tables`` by default. 63 64 Database support 65 ---------------- 66 67 When you use a backend that lacks support for tablespaces, Django ignores all 68 tablespace-related options. 69 70 Here is the current support matrix: 71 72 =================== =================== =========== 73 Database Tables Indexes 74 =================== =================== =========== 75 SQLite no no 76 PostgreSQL yes yes 77 MySQL partial, see below no 78 Oracle yes yes 79 =================== =================== =================== 80 81 MySQL supports tablespaces since version 5.1.6. They're only useful in 82 combination with MySQL Cluster NDB. 83 84 .. versionchanged:: 1.4 85 Until Django 1.4, tablespaces were only supported by the Oracle backend. -
docs/topics/db/index.txt
17 17 sql 18 18 transactions 19 19 multi-db 20 tablespaces 20 21 optimization -
docs/releases/1.4.txt
245 245 code are slightly emphasized. This change makes it easier to scan a stacktrace 246 246 for issues in user code. 247 247 248 * :doc:`Tablespace support </topics/db/tablespaces>` in PostgreSQL and MySQL. 249 248 250 * Customizable names for :meth:`~django.template.Library.simple_tag`. 249 251 250 252 * In the documentation, a helpful :doc:`security overview </topics/security>` -
docs/ref/models/fields.txt
178 178 179 179 .. attribute:: Field.db_tablespace 180 180 181 The name of the database tablespace to use for this field's index, if this field 182 is indexed. The default is the project's :setting:`DEFAULT_INDEX_TABLESPACE` 183 setting, if set, or the :attr:`~Field.db_tablespace` of the model, if any. If 184 the backend doesn't support tablespaces, this option is ignored. 181 The name of the :doc:`database tablespace </topics/db/tablespaces>` to use for 182 this field's index, if this field is indexed. The default is the project's 183 :setting:`DEFAULT_INDEX_TABLESPACE` setting, if set, or the 184 :attr:`~Options.db_tablespace` of the model, if any. If the backend doesn't 185 support tablespaces for indexes, this option is ignored. 185 186 186 187 ``default`` 187 188 ----------- -
docs/ref/models/options.txt
66 66 67 67 .. attribute:: Options.db_tablespace 68 68 69 The name of the database tablespace to use for the model. If the backend 70 doesn't support tablespaces, this option is ignored. 69 The name of the :doc:`database tablespace </topics/db/tablespaces>` to use 70 for this model. The default is the project's :setting:`DEFAULT_TABLESPACE` 71 setting, if set. If the backend doesn't support tablespaces, this option is 72 ignored. 71 73 72 74 ``get_latest_by`` 73 75 ----------------- -
docs/ref/databases.txt
620 620 In this case, the Oracle backend will use a separate ``SELECT`` query to 621 621 retrieve AutoField values. 622 622 623 Tablespace options624 ------------------625 626 A common paradigm for optimizing performance in Oracle-based systems is the627 use of `tablespaces`_ to organize disk layout. The Oracle backend supports628 this use case by adding ``db_tablespace`` options to the ``Meta`` and629 ``Field`` classes. (When you use a backend that lacks support for tablespaces,630 Django ignores these options.)631 632 .. _`tablespaces`: http://en.wikipedia.org/wiki/Tablespace633 634 A tablespace can be specified for the table(s) generated by a model by635 supplying the ``db_tablespace`` option inside the model's ``class Meta``.636 Additionally, you can pass the ``db_tablespace`` option to a ``Field``637 constructor to specify an alternate tablespace for the ``Field``'s column638 index. If no index would be created for the column, the ``db_tablespace``639 option is ignored::640 641 class TablespaceExample(models.Model):642 name = models.CharField(max_length=30, db_index=True, db_tablespace="indexes")643 data = models.CharField(max_length=255, db_index=True)644 edges = models.ManyToManyField(to="self", db_tablespace="indexes")645 646 class Meta:647 db_tablespace = "tables"648 649 In this example, the tables generated by the ``TablespaceExample`` model650 (i.e., the model table and the many-to-many table) would be stored in the651 ``tables`` tablespace. The index for the name field and the indexes on the652 many-to-many table would be stored in the ``indexes`` tablespace. The ``data``653 field would also generate an index, but no tablespace for it is specified, so654 it would be stored in the model tablespace ``tables`` by default.655 656 Use the :setting:`DEFAULT_TABLESPACE` and :setting:`DEFAULT_INDEX_TABLESPACE`657 settings to specify default values for the db_tablespace options.658 These are useful for setting a tablespace for the built-in Django apps and659 other applications whose code you cannot control.660 661 Django does not create the tablespaces for you. Please refer to `Oracle's662 documentation`_ for details on creating and managing tablespaces.663 664 .. _`Oracle's documentation`: http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_7003.htm#SQLRF01403665 666 623 Naming issues 667 624 ------------- 668 625 -
docs/ref/settings.txt
857 857 Default: ``''`` (Empty string) 858 858 859 859 Default tablespace to use for indexes on fields that don't specify 860 one, if the backend supports it .860 one, if the backend supports it (see :doc:`/topics/db/tablespaces`). 861 861 862 862 .. setting:: DEFAULT_TABLESPACE 863 863 … … 867 867 Default: ``''`` (Empty string) 868 868 869 869 Default tablespace to use for models that don't specify one, if the 870 backend supports it .870 backend supports it (see :doc:`/topics/db/tablespaces`). 871 871 872 872 .. setting:: DISALLOWED_USER_AGENTS 873 873 -
tests/modeltests/tablespaces/tests.py
1 from django.db import connection 2 from django.db import models 3 from django.core.management.color import no_style 4 from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature 5 6 from models import Article, ArticleRef, Scientist, ScientistRef 7 8 # Automatically created models 9 Authors = Article._meta.get_field('authors').rel.through 10 Reviewers = Article._meta.get_field('reviewers').rel.through 11 12 # We can't test the DEFAULT_TABLESPACE and DEFAULT_INDEX_TABLESPACE settings 13 # because they're evaluated when the model class is defined. As a consequence, 14 # @override_settings won't work. 15 16 def sql_for_table(model): 17 return '\n'.join(connection.creation.sql_create_model(model, no_style())[0]) 18 19 def sql_for_index(model): 20 return '\n'.join(connection.creation.sql_indexes_for_model(model, no_style())) 21 22 23 class TablespacesTests(TestCase): 24 25 def setUp(self): 26 for model in Article, Authors, Reviewers, Scientist: 27 model._meta.managed = True 28 29 def tearDown(self): 30 for model in Article, Authors, Reviewers, Scientist: 31 model._meta.managed = False 32 33 def assertNumContains(self, haystack, needle, count): 34 real_count = haystack.count(needle) 35 self.assertEqual(real_count, count, "Found %d instances of '%s', " 36 "expected %d" % (real_count, needle, count)) 37 38 @skipUnlessDBFeature('supports_tablespaces') 39 @skipUnlessDBFeature('supports_index_tablespaces') 40 def test_tablespace_for_model(self): 41 # 1 for the table + 1 for the index on the primary key 42 self.assertNumContains(sql_for_table(Scientist), 'tbl_tbsp', 2) 43 44 @skipUnlessDBFeature('supports_tablespaces') 45 @skipIfDBFeature('supports_index_tablespaces') 46 def test_tablespace_for_model_without_index(self): 47 # 1 for the table 48 self.assertNumContains(sql_for_table(Scientist), 'tbl_tbsp', 1) 49 50 @skipIfDBFeature('supports_tablespaces') 51 def test_tablespace_ignored_for_model(self): 52 # No tablespace-related SQL 53 self.assertEqual(sql_for_table(Scientist), 54 sql_for_table(ScientistRef).replace('ref', '')) 55 56 @skipUnlessDBFeature('supports_tablespaces') 57 @skipUnlessDBFeature('supports_index_tablespaces') 58 def test_tablespace_for_indexed_field(self): 59 # 1 for the table + 1 for the primary key + 1 for the index on name 60 self.assertNumContains(sql_for_table(Article), 'tbl_tbsp', 3) 61 # 1 for the index on reference 62 self.assertNumContains(sql_for_table(Article), 'idx_tbsp', 1) 63 64 @skipUnlessDBFeature('supports_tablespaces') 65 @skipIfDBFeature('supports_index_tablespaces') 66 def test_tablespace_for_indexed_field(self): 67 # 1 for the table 68 self.assertNumContains(sql_for_table(Article), 'tbl_tbsp', 1) 69 self.assertNumContains(sql_for_table(Article), 'idx_tbsp', 0) 70 71 @skipIfDBFeature('supports_tablespaces') 72 def test_tablespace_ignored_for_indexed_field(self): 73 # No tablespace-related SQL 74 self.assertEqual(sql_for_table(Article), 75 sql_for_table(ArticleRef).replace('ref', '')) 76 77 @skipUnlessDBFeature('supports_tablespaces') 78 @skipUnlessDBFeature('supports_index_tablespaces') 79 def test_tablespace_for_many_to_many_field(self): 80 # The join table of the ManyToManyField always goes to the tablespace 81 # of the model. 82 self.assertNumContains(sql_for_table(Authors), 'tbl_tbsp', 2) 83 self.assertNumContains(sql_for_table(Authors), 'idx_tbsp', 0) 84 # The ManyToManyField declares no db_tablespace, indexes for the two 85 # foreign keys in the join table go to the tablespace of the model. 86 self.assertNumContains(sql_for_index(Authors), 'tbl_tbsp', 2) 87 self.assertNumContains(sql_for_index(Authors), 'idx_tbsp', 0) 88 89 # The join table of the ManyToManyField always goes to the tablespace 90 # of the model. 91 self.assertNumContains(sql_for_table(Reviewers), 'tbl_tbsp', 2) 92 self.assertNumContains(sql_for_table(Reviewers), 'idx_tbsp', 0) 93 # The ManyToManyField declares db_tablespace, indexes for the two 94 # foreign keys in the join table go to this tablespace. 95 self.assertNumContains(sql_for_index(Reviewers), 'tbl_tbsp', 0) 96 self.assertNumContains(sql_for_index(Reviewers), 'idx_tbsp', 2) -
tests/modeltests/tablespaces/models.py
1 from django.db import models 2 3 # Since the test database doesn't have tablespaces, it's impossible for Django 4 # to create the tables for models where db_tablespace is set. To avoid this 5 # problem, we mark the models as unmanaged, and temporarily revert them to 6 # managed during each test (see setUp and tearDown). 7 8 class ScientistRef(models.Model): 9 name = models.CharField(max_length=50) 10 11 class ArticleRef(models.Model): 12 title = models.CharField(max_length=50, unique=True) 13 code = models.CharField(max_length=50, unique=True) 14 authors = models.ManyToManyField(ScientistRef, related_name='articles_written_set') 15 reviewers = models.ManyToManyField(ScientistRef, related_name='articles_reviewed_set') 16 17 class Scientist(models.Model): 18 name = models.CharField(max_length=50) 19 class Meta: 20 db_tablespace = 'tbl_tbsp' 21 managed = False 22 23 class Article(models.Model): 24 title = models.CharField(max_length=50, unique=True) 25 code = models.CharField(max_length=50, unique=True, db_tablespace='idx_tbsp') 26 authors = models.ManyToManyField(Scientist, related_name='articles_written_set') 27 reviewers = models.ManyToManyField(Scientist, related_name='articles_reviewed_set', db_tablespace='idx_tbsp') 28 class Meta: 29 db_tablespace = 'tbl_tbsp' 30 managed = False -
django/db/models/fields/related.py
988 988 'managed': managed, 989 989 'auto_created': klass, 990 990 'app_label': klass._meta.app_label, 991 'db_tablespace': klass._meta.db_tablespace, 991 992 'unique_together': (from_, to), 992 993 'verbose_name': '%(from)s-%(to)s relationship' % {'from': from_, 'to': to}, 993 994 'verbose_name_plural': '%(from)s-%(to)s relationships' % {'from': from_, 'to': to}, … … 996 997 return type(name, (models.Model,), { 997 998 'Meta': meta, 998 999 '__module__': klass.__module__, 999 from_: models.ForeignKey(klass, related_name='%s+' % name ),1000 to: models.ForeignKey(to_model, related_name='%s+' % name )1000 from_: models.ForeignKey(klass, related_name='%s+' % name, db_tablespace=field.db_tablespace), 1001 to: models.ForeignKey(to_model, related_name='%s+' % name, db_tablespace=field.db_tablespace) 1001 1002 }) 1002 1003 1003 1004 class ManyToManyField(RelatedField, Field): -
django/db/backends/sqlite3/base.py
58 58 supports_unspecified_pk = True 59 59 supports_1000_query_parameters = False 60 60 supports_mixed_date_datetime_comparisons = False 61 supports_index_tablespaces = False 61 62 62 63 def _supports_stddev(self): 63 64 """Confirm support for STDDEV and related stats functions … … 77 78 cursor.execute('DROP TABLE STDDEV_TEST') 78 79 return has_support 79 80 81 def _supports_tablespaces(self): 82 return False 83 80 84 class DatabaseOperations(BaseDatabaseOperations): 81 85 def date_extract_sql(self, lookup_type, field_name): 82 86 # sqlite doesn't support extract, so we fake it with the user-defined … … 129 133 # sql_flush() implementations). Just return SQL at this point 130 134 return sql 131 135 136 def tablespace_sql(self, tablespace, inline=False, index=False): 137 return '' 138 132 139 def year_lookup_bounds(self, value): 133 140 first = '%s-01-01' 134 141 second = '%s-12-31 23:59:59.999999' -
django/db/backends/mysql/base.py
134 134 supports_timezones = False 135 135 requires_explicit_null_ordering_when_grouping = True 136 136 allows_primary_key_0 = False 137 supports_index_tablespaces = False 137 138 138 139 def _can_introspect_foreign_keys(self): 139 140 "Confirm support for introspected foreign keys" … … 148 149 cursor.execute('DROP TABLE INTROSPECT_TEST') 149 150 return result[1] != 'MyISAM' 150 151 152 def _supports_tablespaces(self): 153 "Confirm support for tablespaces" 154 return self.connection.get_server_version() >= (5, 1, 6) 155 151 156 class DatabaseOperations(BaseDatabaseOperations): 152 157 compiler_module = "django.db.backends.mysql.compiler" 153 158 … … 232 237 else: 233 238 return [] 234 239 240 def tablespace_sql(self, tablespace, inline=False, index=False): 241 # MySQL doesn't support setting tablespaces for indexes, and it only 242 # supports setting tablespaces for table since version 5.1.6 243 if inline or index or self.connection.get_server_version() < (5, 1, 6): 244 return '' 245 return super(DatabaseOperations, self).tablespace_sql(tablespace, 246 inline=inline, index=index) 247 235 248 def value_to_db_datetime(self, value): 236 249 if value is None: 237 250 return None -
django/db/backends/oracle/base.py
324 324 def start_transaction_sql(self): 325 325 return '' 326 326 327 def tablespace_sql(self, tablespace, inline=False):328 return "%sTABLESPACE %s" % ((inline and "USING INDEX " or ""),329 self.quote_name(tablespace))330 331 327 def value_to_db_datetime(self, value): 332 328 # Oracle doesn't support tz-aware datetimes 333 329 if getattr(value, 'tzinfo', None) is not None: -
django/db/backends/__init__.py
364 364 # date_interval_sql can properly handle mixed Date/DateTime fields and timedeltas 365 365 supports_mixed_date_datetime_comparisons = True 366 366 367 # Does the backend support tablespaces for indexes? 368 # Requires supports_tablespaces = True. 369 supports_index_tablespaces = True 370 367 371 # Features that need to be confirmed at runtime 372 368 373 # Cache whether the confirmation has been performed. 369 374 _confirmed = False 370 375 supports_transactions = None 371 376 supports_stddev = None 372 377 can_introspect_foreign_keys = None 378 # Does the backend support tablespaces for tables? 379 supports_tablespaces = None 373 380 374 381 def __init__(self, connection): 375 382 self.connection = connection … … 380 387 self.supports_transactions = self._supports_transactions() 381 388 self.supports_stddev = self._supports_stddev() 382 389 self.can_introspect_foreign_keys = self._can_introspect_foreign_keys() 390 self.supports_tablespaces = self._supports_tablespaces() 383 391 384 392 def _supports_transactions(self): 385 393 "Confirm support for transactions" … … 410 418 # which can't do it for MyISAM tables 411 419 return True 412 420 421 def _supports_tablespaces(self): 422 "Confirm support for tablespaces" 423 # On MySQL, this depends on the version 424 return True 413 425 426 414 427 class BaseDatabaseOperations(object): 415 428 """ 416 429 This class encapsulates all backend-specific differences, such as the way … … 693 706 return "ROLLBACK;" 694 707 return "COMMIT;" 695 708 696 def tablespace_sql(self, tablespace, inline=False ):709 def tablespace_sql(self, tablespace, inline=False, index=False): 697 710 """ 698 Returns the SQL that will be appended to tables or rows to define 699 a tablespace. Returns '' if the backend doesn't use tablespaces. 711 Returns the SQL that will be used in a query to define the tablespace. 712 713 Returns '' if the backend doesn't support tablespaces. 714 715 If inline is True, the SQL is appended to a row; otherwise it's appended 716 to the entire statement. If index is True, the statement creates an 717 index; otherwise it creates a table. 718 719 SQL added to a row applies to the index created by this row. When inline 720 is True, it implies that index is True, even if the caller doesn't pass 721 the index parameter. 700 722 """ 701 return '' 723 if inline: 724 return "USING INDEX TABLESPACE %s" % self.quote_name(tablespace) 725 else: 726 return "TABLESPACE %s" % self.quote_name(tablespace) 702 727 703 728 def prep_for_like_query(self, x): 704 729 """Prepares a value for use in a LIKE query.""" -
django/db/backends/postgresql_psycopg2/creation.py
44 44 db_table = model._meta.db_table 45 45 tablespace = f.db_tablespace or model._meta.db_tablespace 46 46 if tablespace: 47 sql = self.connection.ops.tablespace_sql(tablespace) 48 if sql: 49 tablespace_sql = ' ' + sql 50 else: 51 tablespace_sql = '' 47 tablespace_sql = self.connection.ops.tablespace_sql(tablespace, index=True) 48 if tablespace_sql: 49 tablespace_sql = ' ' + tablespace_sql 52 50 else: 53 51 tablespace_sql = '' 54 52 -
django/db/backends/creation.py
57 57 if tablespace and f.unique: 58 58 # We must specify the index tablespace inline, because we 59 59 # won't be generating a CREATE INDEX statement for this field. 60 field_output.append(self.connection.ops.tablespace_sql(tablespace, inline=True)) 60 tablespace_sql = self.connection.ops.tablespace_sql(tablespace, inline=True) 61 if tablespace_sql: 62 field_output.append(tablespace_sql) 61 63 if f.rel: 62 64 ref_output, pending = self.sql_for_inline_foreign_key_references(f, known_models, style) 63 65 if pending: … … 74 76 full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or '')) 75 77 full_statement.append(')') 76 78 if opts.db_tablespace: 77 full_statement.append(self.connection.ops.tablespace_sql(opts.db_tablespace)) 79 tablespace_sql = self.connection.ops.tablespace_sql(opts.db_tablespace) 80 if tablespace_sql: 81 full_statement.append(tablespace_sql) 78 82 full_statement.append(';') 79 83 final_output.append('\n'.join(full_statement)) 80 84 … … 149 153 qn = self.connection.ops.quote_name 150 154 tablespace = f.db_tablespace or model._meta.db_tablespace 151 155 if tablespace: 152 sql = self.connection.ops.tablespace_sql(tablespace) 153 if sql: 154 tablespace_sql = ' ' + sql 155 else: 156 tablespace_sql = '' 156 tablespace_sql = self.connection.ops.tablespace_sql(tablespace, index=True) 157 if tablespace_sql: 158 tablespace_sql = ' ' + tablespace_sql 157 159 else: 158 160 tablespace_sql = '' 159 161 i_name = '%s_%s' % (model._meta.db_table, self._digest(f.column))