summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2020-06-23 23:43:22 -0400
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-06-24 08:37:20 +0200
commit2e8941b6f90e65ffad3f07083b8de59e8ed29767 (patch)
tree6670a9b68ad06460f22af02312db4c8a617aa08c
parent6f3e3e87ab72eb64dcce8e646f8eea07be6c3b7e (diff)
Fixed #31735 -- Fixed migrations crash on namespaced inline FK addition on PostgreSQL.
The namespace of the constraint must be included when making the constraint immediate. Regression in 22ce5d0031bd795ade081394043833e82046016c. Thanks Rodrigo Estevao for the report.
-rw-r--r--django/db/backends/base/schema.py2
-rw-r--r--django/db/backends/postgresql/schema.py2
-rw-r--r--docs/releases/3.0.8.txt4
-rw-r--r--tests/schema/tests.py29
4 files changed, 36 insertions, 1 deletions
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: