diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py index 76dea84cff..c8dc8e3a70 100644 --- a/django/db/backends/base/schema.py +++ b/django/db/backends/base/schema.py @@ -466,8 +466,10 @@ class BaseDatabaseSchemaEditor: if self.sql_create_column_inline_fk: to_table = field.remote_field.model._meta.db_table to_column = field.remote_field.model._meta.get_field(field.remote_field.field_name).column + namespace, _ = split_identifier(model._meta.db_table) definition += " " + self.sql_create_column_inline_fk % { 'name': self._fk_constraint_name(model, field, constraint_suffix), + 'namespace': '%s.' % self.quote_name(namespace) if namespace else '', 'column': self.quote_name(field.column), 'to_table': self.quote_name(to_table), 'to_column': self.quote_name(to_column), diff --git a/django/db/backends/postgresql/schema.py b/django/db/backends/postgresql/schema.py index fbc4a59dc4..7687c37fe7 100644 --- a/django/db/backends/postgresql/schema.py +++ b/django/db/backends/postgresql/schema.py @@ -27,7 +27,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): # transaction. sql_create_column_inline_fk = ( 'CONSTRAINT %(name)s REFERENCES %(to_table)s(%(to_column)s)%(deferrable)s' - '; SET CONSTRAINTS %(name)s IMMEDIATE' + '; SET CONSTRAINTS %(namespace)s%(name)s IMMEDIATE' ) # Setting the constraint to IMMEDIATE runs any deferred checks to allow # dropping it in the same transaction. diff --git a/docs/releases/3.0.8.txt b/docs/releases/3.0.8.txt index 6bb3e39de7..f23208f9ae 100644 --- a/docs/releases/3.0.8.txt +++ b/docs/releases/3.0.8.txt @@ -18,3 +18,7 @@ Bugfixes * Reallowed, following a regression in Django 3.0, non-expressions having a ``filterable`` attribute to be used as the right-hand side in queryset filters (:ticket:`31664`). + +* Fixed a regression in Django 3.0.2 that caused a migration crash on + PostgreSQL when adding a foreign key to a model with a namespaced + ``db_table`` (:ticket:`31735`). diff --git a/tests/schema/tests.py b/tests/schema/tests.py index 5868d520e8..19b0a1dcc7 100644 --- a/tests/schema/tests.py +++ b/tests/schema/tests.py @@ -3060,6 +3060,35 @@ class SchemaTests(TransactionTestCase): student = Student.objects.create(name='Some man') doc.students.add(student) + @isolate_apps('schema') + @unittest.skipUnless(connection.vendor == 'postgresql', 'PostgreSQL specific db_table syntax.') + def test_namespaced_db_table_foreign_key_reference(self): + with connection.cursor() as cursor: + cursor.execute('CREATE SCHEMA django_schema_tests') + + def delete_schema(): + with connection.cursor() as cursor: + cursor.execute('DROP SCHEMA django_schema_tests CASCADE') + + self.addCleanup(delete_schema) + + class Author(Model): + class Meta: + app_label = 'schema' + + class Book(Model): + class Meta: + app_label = 'schema' + db_table = '"django_schema_tests"."schema_book"' + + author = ForeignKey(Author, CASCADE) + author.set_attributes_from_name('author') + + with connection.schema_editor() as editor: + editor.create_model(Author) + editor.create_model(Book) + editor.add_field(Book, author) + def test_rename_table_renames_deferred_sql_references(self): atomic_rename = connection.features.supports_atomic_references_rename with connection.schema_editor(atomic=atomic_rename) as editor: