mirror of
				https://github.com/django/django.git
				synced 2025-10-30 23:47:49 +03:00 
			
		
		
		
	Fixed #12308 -- Added tablespace support to the PostgreSQL backend.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16987 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		
							parent
							
								
									69e1e6187a
								
							
						
					
					
						commit
						246580573d
					
				|  | @ -365,6 +365,10 @@ class BaseDatabaseFeatures(object): | |||
|     # date_interval_sql can properly handle mixed Date/DateTime fields and timedeltas | ||||
|     supports_mixed_date_datetime_comparisons = True | ||||
| 
 | ||||
|     # Does the backend support tablespaces? Default to False because it isn't | ||||
|     # in the SQL standard. | ||||
|     supports_tablespaces = False | ||||
| 
 | ||||
|     # Features that need to be confirmed at runtime | ||||
|     # Cache whether the confirmation has been performed. | ||||
|     _confirmed = False | ||||
|  | @ -696,8 +700,12 @@ class BaseDatabaseOperations(object): | |||
| 
 | ||||
|     def tablespace_sql(self, tablespace, inline=False): | ||||
|         """ | ||||
|         Returns the SQL that will be appended to tables or rows to define | ||||
|         a tablespace. Returns '' if the backend doesn't use tablespaces. | ||||
|         Returns the SQL that will be used in a query to define the tablespace. | ||||
| 
 | ||||
|         Returns '' if the backend doesn't support tablespaces. | ||||
| 
 | ||||
|         If inline is True, the SQL is appended to a row; otherwise it's appended | ||||
|         to the entire CREATE TABLE or CREATE INDEX statement. | ||||
|         """ | ||||
|         return '' | ||||
| 
 | ||||
|  |  | |||
|  | @ -57,7 +57,9 @@ class BaseDatabaseCreation(object): | |||
|             if tablespace and f.unique: | ||||
|                 # We must specify the index tablespace inline, because we | ||||
|                 # won't be generating a CREATE INDEX statement for this field. | ||||
|                 field_output.append(self.connection.ops.tablespace_sql(tablespace, inline=True)) | ||||
|                 tablespace_sql = self.connection.ops.tablespace_sql(tablespace, inline=True) | ||||
|                 if tablespace_sql: | ||||
|                     field_output.append(tablespace_sql) | ||||
|             if f.rel: | ||||
|                 ref_output, pending = self.sql_for_inline_foreign_key_references(f, known_models, style) | ||||
|                 if pending: | ||||
|  | @ -74,7 +76,9 @@ class BaseDatabaseCreation(object): | |||
|             full_statement.append('    %s%s' % (line, i < len(table_output)-1 and ',' or '')) | ||||
|         full_statement.append(')') | ||||
|         if opts.db_tablespace: | ||||
|             full_statement.append(self.connection.ops.tablespace_sql(opts.db_tablespace)) | ||||
|             tablespace_sql = self.connection.ops.tablespace_sql(opts.db_tablespace) | ||||
|             if tablespace_sql: | ||||
|                 full_statement.append(tablespace_sql) | ||||
|         full_statement.append(';') | ||||
|         final_output.append('\n'.join(full_statement)) | ||||
| 
 | ||||
|  | @ -149,11 +153,9 @@ class BaseDatabaseCreation(object): | |||
|             qn = self.connection.ops.quote_name | ||||
|             tablespace = f.db_tablespace or model._meta.db_tablespace | ||||
|             if tablespace: | ||||
|                 sql = self.connection.ops.tablespace_sql(tablespace) | ||||
|                 if sql: | ||||
|                     tablespace_sql = ' ' + sql | ||||
|                 else: | ||||
|                     tablespace_sql = '' | ||||
|                 tablespace_sql = self.connection.ops.tablespace_sql(tablespace) | ||||
|                 if tablespace_sql: | ||||
|                     tablespace_sql = ' ' + tablespace_sql | ||||
|             else: | ||||
|                 tablespace_sql = '' | ||||
|             i_name = '%s_%s' % (model._meta.db_table, self._digest(f.column)) | ||||
|  |  | |||
|  | @ -79,6 +79,7 @@ class DatabaseFeatures(BaseDatabaseFeatures): | |||
|     can_defer_constraint_checks = True | ||||
|     ignores_nulls_in_unique_constraints = False | ||||
|     has_bulk_insert = True | ||||
|     supports_tablespaces = True | ||||
| 
 | ||||
| class DatabaseOperations(BaseDatabaseOperations): | ||||
|     compiler_module = "django.db.backends.oracle.compiler" | ||||
|  | @ -326,8 +327,10 @@ WHEN (new.%(col_name)s IS NULL) | |||
|         return '' | ||||
| 
 | ||||
|     def tablespace_sql(self, tablespace, inline=False): | ||||
|         return "%sTABLESPACE %s" % ((inline and "USING INDEX " or ""), | ||||
|             self.quote_name(tablespace)) | ||||
|         if inline: | ||||
|             return "USING INDEX TABLESPACE %s" % self.quote_name(tablespace) | ||||
|         else: | ||||
|             return "TABLESPACE %s" % self.quote_name(tablespace) | ||||
| 
 | ||||
|     def value_to_db_datetime(self, value): | ||||
|         # Oracle doesn't support tz-aware datetimes | ||||
|  |  | |||
|  | @ -75,7 +75,7 @@ class DatabaseFeatures(BaseDatabaseFeatures): | |||
|     has_select_for_update = True | ||||
|     has_select_for_update_nowait = True | ||||
|     has_bulk_insert = True | ||||
| 
 | ||||
|     supports_tablespaces = True | ||||
| 
 | ||||
| class DatabaseWrapper(BaseDatabaseWrapper): | ||||
|     vendor = 'postgresql' | ||||
|  |  | |||
|  | @ -44,11 +44,9 @@ class DatabaseCreation(BaseDatabaseCreation): | |||
|             db_table = model._meta.db_table | ||||
|             tablespace = f.db_tablespace or model._meta.db_tablespace | ||||
|             if tablespace: | ||||
|                 sql = self.connection.ops.tablespace_sql(tablespace) | ||||
|                 if sql: | ||||
|                     tablespace_sql = ' ' + sql | ||||
|                 else: | ||||
|                     tablespace_sql = '' | ||||
|                 tablespace_sql = self.connection.ops.tablespace_sql(tablespace) | ||||
|                 if tablespace_sql: | ||||
|                     tablespace_sql = ' ' + tablespace_sql | ||||
|             else: | ||||
|                 tablespace_sql = '' | ||||
| 
 | ||||
|  |  | |||
|  | @ -99,6 +99,12 @@ class DatabaseOperations(BaseDatabaseOperations): | |||
|         else: | ||||
|             return [] | ||||
| 
 | ||||
|     def tablespace_sql(self, tablespace, inline=False): | ||||
|         if inline: | ||||
|             return "USING INDEX TABLESPACE %s" % self.quote_name(tablespace) | ||||
|         else: | ||||
|             return "TABLESPACE %s" % self.quote_name(tablespace) | ||||
| 
 | ||||
|     def sequence_reset_sql(self, style, model_list): | ||||
|         from django.db import models | ||||
|         output = [] | ||||
|  |  | |||
|  | @ -1078,6 +1078,7 @@ def create_many_to_many_intermediary_model(field, klass): | |||
|         'managed': managed, | ||||
|         'auto_created': klass, | ||||
|         'app_label': klass._meta.app_label, | ||||
|         'db_tablespace': klass._meta.db_tablespace, | ||||
|         'unique_together': (from_, to), | ||||
|         'verbose_name': '%(from)s-%(to)s relationship' % {'from': from_, 'to': to}, | ||||
|         'verbose_name_plural': '%(from)s-%(to)s relationships' % {'from': from_, 'to': to}, | ||||
|  | @ -1086,8 +1087,8 @@ def create_many_to_many_intermediary_model(field, klass): | |||
|     return type(name, (models.Model,), { | ||||
|         'Meta': meta, | ||||
|         '__module__': klass.__module__, | ||||
|         from_: models.ForeignKey(klass, related_name='%s+' % name), | ||||
|         to: models.ForeignKey(to_model, related_name='%s+' % name) | ||||
|         from_: models.ForeignKey(klass, related_name='%s+' % name, db_tablespace=field.db_tablespace), | ||||
|         to: models.ForeignKey(to_model, related_name='%s+' % name, db_tablespace=field.db_tablespace) | ||||
|     }) | ||||
| 
 | ||||
| class ManyToManyField(RelatedField, Field): | ||||
|  |  | |||
|  | @ -219,9 +219,9 @@ parameters: | |||
| * :attr:`~django.db.models.Field.choices` | ||||
| * :attr:`~django.db.models.Field.help_text` | ||||
| * :attr:`~django.db.models.Field.db_column` | ||||
| * :attr:`~django.db.models.Field.db_tablespace`: Currently only used with | ||||
|   the Oracle backend and only for index creation. You can usually ignore | ||||
|   this option. | ||||
| * :attr:`~django.db.models.Field.db_tablespace`: Only for index creation, if the | ||||
|   backend supports :doc:`tablespaces </topics/db/tablespaces>`. You can usually | ||||
|   ignore this option. | ||||
| * :attr:`~django.db.models.Field.auto_created`: True if the field was | ||||
|   automatically created, as for the `OneToOneField` used by model | ||||
|   inheritance. For advanced use only. | ||||
|  |  | |||
|  | @ -646,49 +646,6 @@ The ``RETURNING INTO`` clause can be disabled by setting the | |||
| In this case, the Oracle backend will use a separate ``SELECT`` query to | ||||
| retrieve AutoField values. | ||||
| 
 | ||||
| Tablespace options | ||||
| ------------------ | ||||
| 
 | ||||
| A common paradigm for optimizing performance in Oracle-based systems is the | ||||
| use of `tablespaces`_ to organize disk layout. The Oracle backend supports | ||||
| this use case by adding ``db_tablespace`` options to the ``Meta`` and | ||||
| ``Field`` classes.  (When you use a backend that lacks support for tablespaces, | ||||
| Django ignores these options.) | ||||
| 
 | ||||
| .. _`tablespaces`: http://en.wikipedia.org/wiki/Tablespace | ||||
| 
 | ||||
| A tablespace can be specified for the table(s) generated by a model by | ||||
| supplying the ``db_tablespace`` option inside the model's ``class Meta``. | ||||
| Additionally, you can pass the ``db_tablespace`` option to a ``Field`` | ||||
| constructor to specify an alternate tablespace for the ``Field``'s column | ||||
| index. If no index would be created for the column, the ``db_tablespace`` | ||||
| option is ignored:: | ||||
| 
 | ||||
|     class TablespaceExample(models.Model): | ||||
|         name = models.CharField(max_length=30, db_index=True, db_tablespace="indexes") | ||||
|         data = models.CharField(max_length=255, db_index=True) | ||||
|         edges = models.ManyToManyField(to="self", db_tablespace="indexes") | ||||
| 
 | ||||
|         class Meta: | ||||
|             db_tablespace = "tables" | ||||
| 
 | ||||
| In this example, the tables generated by the ``TablespaceExample`` model | ||||
| (i.e., the model table and the many-to-many table) would be stored in the | ||||
| ``tables`` tablespace. The index for the name field and the indexes on the | ||||
| many-to-many table would be stored in the ``indexes`` tablespace. The ``data`` | ||||
| field would also generate an index, but no tablespace for it is specified, so | ||||
| it would be stored in the model tablespace ``tables`` by default. | ||||
| 
 | ||||
| Use the :setting:`DEFAULT_TABLESPACE` and :setting:`DEFAULT_INDEX_TABLESPACE` | ||||
| settings to specify default values for the db_tablespace options. | ||||
| These are useful for setting a tablespace for the built-in Django apps and | ||||
| other applications whose code you cannot control. | ||||
| 
 | ||||
| Django does not create the tablespaces for you. Please refer to `Oracle's | ||||
| documentation`_ for details on creating and managing tablespaces. | ||||
| 
 | ||||
| .. _`Oracle's documentation`: http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_7003.htm#SQLRF01403 | ||||
| 
 | ||||
| Naming issues | ||||
| ------------- | ||||
| 
 | ||||
|  |  | |||
|  | @ -178,10 +178,11 @@ If ``True``, djadmin:`django-admin.py sqlindexes <sqlindexes>` will output a | |||
| 
 | ||||
| .. attribute:: Field.db_tablespace | ||||
| 
 | ||||
| The name of the database tablespace to use for this field's index, if this field | ||||
| is indexed. The default is the project's :setting:`DEFAULT_INDEX_TABLESPACE` | ||||
| setting, if set, or the :attr:`~Field.db_tablespace` of the model, if any. If | ||||
| the backend doesn't support tablespaces, this option is ignored. | ||||
| The name of the :doc:`database tablespace </topics/db/tablespaces>` to use for | ||||
| this field's index, if this field is indexed. The default is the project's | ||||
| :setting:`DEFAULT_INDEX_TABLESPACE` setting, if set, or the | ||||
| :attr:`~Options.db_tablespace` of the model, if any. If the backend doesn't | ||||
| support tablespaces for indexes, this option is ignored. | ||||
| 
 | ||||
| ``default`` | ||||
| ----------- | ||||
|  |  | |||
|  | @ -73,8 +73,10 @@ Django quotes column and table names behind the scenes. | |||
| 
 | ||||
| .. attribute:: Options.db_tablespace | ||||
| 
 | ||||
|     The name of the database tablespace to use for the model. If the backend | ||||
|     doesn't support tablespaces, this option is ignored. | ||||
|     The name of the :doc:`database tablespace </topics/db/tablespaces>` to use | ||||
|     for this model. The default is the project's :setting:`DEFAULT_TABLESPACE` | ||||
|     setting, if set. If the backend doesn't support tablespaces, this option is | ||||
|     ignored. | ||||
| 
 | ||||
| ``get_latest_by`` | ||||
| ----------------- | ||||
|  |  | |||
|  | @ -864,7 +864,7 @@ DEFAULT_INDEX_TABLESPACE | |||
| Default: ``''`` (Empty string) | ||||
| 
 | ||||
| Default tablespace to use for indexes on fields that don't specify | ||||
| one, if the backend supports it. | ||||
| one, if the backend supports it (see :doc:`/topics/db/tablespaces`). | ||||
| 
 | ||||
| .. setting:: DEFAULT_TABLESPACE | ||||
| 
 | ||||
|  | @ -874,7 +874,7 @@ DEFAULT_TABLESPACE | |||
| Default: ``''`` (Empty string) | ||||
| 
 | ||||
| Default tablespace to use for models that don't specify one, if the | ||||
| backend supports it. | ||||
| backend supports it (see :doc:`/topics/db/tablespaces`). | ||||
| 
 | ||||
| .. setting:: DISALLOWED_USER_AGENTS | ||||
| 
 | ||||
|  |  | |||
|  | @ -405,6 +405,8 @@ Django 1.4 also includes several smaller improvements worth noting: | |||
|   code are slightly emphasized. This change makes it easier to scan a stacktrace | ||||
|   for issues in user code. | ||||
| 
 | ||||
| * :doc:`Tablespace support </topics/db/tablespaces>` in PostgreSQL. | ||||
| 
 | ||||
| * Customizable names for :meth:`~django.template.Library.simple_tag`. | ||||
| 
 | ||||
| * In the documentation, a helpful :doc:`security overview </topics/security>` | ||||
|  |  | |||
|  | @ -17,4 +17,5 @@ model maps to a single database table. | |||
|    sql | ||||
|    transactions | ||||
|    multi-db | ||||
|    tablespaces | ||||
|    optimization | ||||
|  |  | |||
							
								
								
									
										73
									
								
								docs/topics/db/tablespaces.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								docs/topics/db/tablespaces.txt
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,73 @@ | |||
| =========== | ||||
| Tablespaces | ||||
| =========== | ||||
| 
 | ||||
| A common paradigm for optimizing performance in database systems is the use of | ||||
| `tablespaces`_ to organize disk layout. | ||||
| 
 | ||||
| .. _`tablespaces`: http://en.wikipedia.org/wiki/Tablespace | ||||
| 
 | ||||
| .. warning:: | ||||
|     Django does not create the tablespaces for you. Please refer to your | ||||
|     database engine's documentation for details on creating and managing | ||||
|     tablespaces. | ||||
| 
 | ||||
| 
 | ||||
| Declaring tablespaces for tables | ||||
| -------------------------------- | ||||
| 
 | ||||
| A tablespace can be specified for the table generated by a model by supplying | ||||
| the :attr:`~django.db.models.Options.db_tablespace` option inside the model's | ||||
| ``class Meta``. This option also affects tables automatically created for | ||||
| :class:`~django.db.models.ManyToManyField`\ s in the model. | ||||
| 
 | ||||
| You can use the :setting:`DEFAULT_TABLESPACE` setting to specify a default value | ||||
| for :attr:`~django.db.models.Options.db_tablespace`. This is useful for setting | ||||
| a tablespace for the built-in Django apps and other applications whose code you | ||||
| cannot control. | ||||
| 
 | ||||
| Declaring tablespaces for indexes | ||||
| --------------------------------- | ||||
| 
 | ||||
| You can pass the :attr:`~django.db.models.Field.db_tablespace` option to a | ||||
| ``Field`` constructor to specify an alternate tablespace for the ``Field``'s | ||||
| column index. If no index would be created for the column, the option is | ||||
| ignored. | ||||
| 
 | ||||
| You can use the :setting:`DEFAULT_INDEX_TABLESPACE` setting to specify | ||||
| a default value for :attr:`~django.db.models.Field.db_tablespace`. | ||||
| 
 | ||||
| If :attr:`~django.db.models.Field.db_tablespace` isn't specified and you didn't | ||||
| set :setting:`DEFAULT_INDEX_TABLESPACE`, the index is created in the same | ||||
| tablespace as the tables. | ||||
| 
 | ||||
| An example | ||||
| ---------- | ||||
| 
 | ||||
| .. code-block:: python | ||||
| 
 | ||||
|     class TablespaceExample(models.Model): | ||||
|         name = models.CharField(max_length=30, db_index=True, db_tablespace="indexes") | ||||
|         data = models.CharField(max_length=255, db_index=True) | ||||
|         edges = models.ManyToManyField(to="self", db_tablespace="indexes") | ||||
| 
 | ||||
|         class Meta: | ||||
|             db_tablespace = "tables" | ||||
| 
 | ||||
| In this example, the tables generated by the ``TablespaceExample`` model (i.e. | ||||
| the model table and the many-to-many table) would be stored in the ``tables`` | ||||
| tablespace. The index for the name field and the indexes on the many-to-many | ||||
| table would be stored in the ``indexes`` tablespace. The ``data`` field would | ||||
| also generate an index, but no tablespace for it is specified, so it would be | ||||
| stored in the model tablespace ``tables`` by default. | ||||
| 
 | ||||
| Database support | ||||
| ---------------- | ||||
| 
 | ||||
| PostgreSQL and Oracle support tablespaces. SQLite and MySQL don't. | ||||
| 
 | ||||
| When you use a backend that lacks support for tablespaces, Django ignores all | ||||
| tablespace-related options. | ||||
| 
 | ||||
| .. versionchanged:: 1.4 | ||||
|     Since Django 1.4, the PostgreSQL backend supports tablespaces. | ||||
							
								
								
									
										0
									
								
								tests/modeltests/tablespaces/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								tests/modeltests/tablespaces/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										32
									
								
								tests/modeltests/tablespaces/models.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								tests/modeltests/tablespaces/models.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | |||
| from django.db import models | ||||
| 
 | ||||
| # Since the test database doesn't have tablespaces, it's impossible for Django | ||||
| # to create the tables for models where db_tablespace is set. To avoid this | ||||
| # problem, we mark the models as unmanaged, and temporarily revert them to | ||||
| # managed during each tes. See setUp and tearDown -- it isn't possible to use | ||||
| # setUpClass and tearDownClass because they're called before Django flushes the | ||||
| # tables, so Django attempts to flush a non-existing table. | ||||
| 
 | ||||
| class ScientistRef(models.Model): | ||||
|     name = models.CharField(max_length=50) | ||||
| 
 | ||||
| class ArticleRef(models.Model): | ||||
|     title = models.CharField(max_length=50, unique=True) | ||||
|     code = models.CharField(max_length=50, unique=True) | ||||
|     authors = models.ManyToManyField(ScientistRef, related_name='articles_written_set') | ||||
|     reviewers = models.ManyToManyField(ScientistRef, related_name='articles_reviewed_set') | ||||
| 
 | ||||
| class Scientist(models.Model): | ||||
|     name = models.CharField(max_length=50) | ||||
|     class Meta: | ||||
|         db_tablespace = 'tbl_tbsp' | ||||
|         managed = False | ||||
| 
 | ||||
| class Article(models.Model): | ||||
|     title = models.CharField(max_length=50, unique=True) | ||||
|     code = models.CharField(max_length=50, unique=True, db_tablespace='idx_tbsp') | ||||
|     authors = models.ManyToManyField(Scientist, related_name='articles_written_set') | ||||
|     reviewers = models.ManyToManyField(Scientist, related_name='articles_reviewed_set', db_tablespace='idx_tbsp') | ||||
|     class Meta: | ||||
|         db_tablespace = 'tbl_tbsp' | ||||
|         managed = False | ||||
							
								
								
									
										92
									
								
								tests/modeltests/tablespaces/tests.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								tests/modeltests/tablespaces/tests.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,92 @@ | |||
| import copy | ||||
| 
 | ||||
| from django.db import connection | ||||
| from django.db import models | ||||
| from django.db.models.loading import cache | ||||
| from django.core.management.color import no_style  | ||||
| from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature | ||||
| 
 | ||||
| from models import Article, ArticleRef, Scientist, ScientistRef | ||||
| 
 | ||||
| # Automatically created models | ||||
| Authors = Article._meta.get_field('authors').rel.through | ||||
| Reviewers = Article._meta.get_field('reviewers').rel.through | ||||
| 
 | ||||
| # We can't test the DEFAULT_TABLESPACE and DEFAULT_INDEX_TABLESPACE settings | ||||
| # because they're evaluated when the model class is defined. As a consequence, | ||||
| # @override_settings doesn't work. | ||||
| 
 | ||||
| def sql_for_table(model): | ||||
|     return '\n'.join(connection.creation.sql_create_model(model, no_style())[0]) | ||||
| 
 | ||||
| def sql_for_index(model): | ||||
|     return '\n'.join(connection.creation.sql_indexes_for_model(model, no_style())) | ||||
| 
 | ||||
| 
 | ||||
| class TablespacesTests(TestCase): | ||||
| 
 | ||||
|     def setUp(self): | ||||
|         # The unmanaged models need to be removed after the test in order to | ||||
|         # prevent bad interactions with other tests (proxy_models_inheritance). | ||||
|         self.old_app_models = copy.deepcopy(cache.app_models) | ||||
|         self.old_app_store = copy.deepcopy(cache.app_store) | ||||
| 
 | ||||
|         for model in Article, Authors, Reviewers, Scientist: | ||||
|             model._meta.managed = True | ||||
| 
 | ||||
|     def tearDown(self): | ||||
|         for model in Article, Authors, Reviewers, Scientist: | ||||
|             model._meta.managed = False | ||||
| 
 | ||||
|         cache.app_models = self.old_app_models | ||||
|         cache.app_store = self.old_app_store | ||||
|         cache._get_models_cache = {} | ||||
| 
 | ||||
|     def assertNumContains(self, haystack, needle, count): | ||||
|         real_count = haystack.count(needle) | ||||
|         self.assertEqual(real_count, count, "Found %d instances of '%s', " | ||||
|                 "expected %d" % (real_count, needle, count)) | ||||
| 
 | ||||
|     @skipUnlessDBFeature('supports_tablespaces') | ||||
|     def test_tablespace_for_model(self): | ||||
|         # 1 for the table + 1 for the index on the primary key | ||||
|         self.assertNumContains(sql_for_table(Scientist).lower(), 'tbl_tbsp', 2) | ||||
| 
 | ||||
|     @skipIfDBFeature('supports_tablespaces') | ||||
|     def test_tablespace_ignored_for_model(self): | ||||
|         # No tablespace-related SQL | ||||
|         self.assertEqual(sql_for_table(Scientist), | ||||
|                          sql_for_table(ScientistRef).replace('ref', '')) | ||||
| 
 | ||||
|     @skipUnlessDBFeature('supports_tablespaces') | ||||
|     def test_tablespace_for_indexed_field(self): | ||||
|         # 1 for the table + 1 for the primary key + 1 for the index on name | ||||
|         self.assertNumContains(sql_for_table(Article).lower(), 'tbl_tbsp', 3) | ||||
|         # 1 for the index on reference | ||||
|         self.assertNumContains(sql_for_table(Article).lower(), 'idx_tbsp', 1) | ||||
| 
 | ||||
|     @skipIfDBFeature('supports_tablespaces') | ||||
|     def test_tablespace_ignored_for_indexed_field(self): | ||||
|         # No tablespace-related SQL | ||||
|         self.assertEqual(sql_for_table(Article), | ||||
|                          sql_for_table(ArticleRef).replace('ref', '')) | ||||
| 
 | ||||
|     @skipUnlessDBFeature('supports_tablespaces') | ||||
|     def test_tablespace_for_many_to_many_field(self): | ||||
|         # The join table of the ManyToManyField always goes to the tablespace | ||||
|         # of the model. | ||||
|         self.assertNumContains(sql_for_table(Authors).lower(), 'tbl_tbsp', 2) | ||||
|         self.assertNumContains(sql_for_table(Authors).lower(), 'idx_tbsp', 0) | ||||
|         # The ManyToManyField declares no db_tablespace, indexes for the two | ||||
|         # foreign keys in the join table go to the tablespace of the model. | ||||
|         self.assertNumContains(sql_for_index(Authors).lower(), 'tbl_tbsp', 2) | ||||
|         self.assertNumContains(sql_for_index(Authors).lower(), 'idx_tbsp', 0) | ||||
| 
 | ||||
|         # The join table of the ManyToManyField always goes to the tablespace | ||||
|         # of the model. | ||||
|         self.assertNumContains(sql_for_table(Reviewers).lower(), 'tbl_tbsp', 2) | ||||
|         self.assertNumContains(sql_for_table(Reviewers).lower(), 'idx_tbsp', 0) | ||||
|         # The ManyToManyField declares db_tablespace, indexes for the two | ||||
|         # foreign keys in the join table go to this tablespace. | ||||
|         self.assertNumContains(sql_for_index(Reviewers).lower(), 'tbl_tbsp', 0) | ||||
|         self.assertNumContains(sql_for_index(Reviewers).lower(), 'idx_tbsp', 2) | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user