Permalink
Browse files

[1.7.x] Fixed #23009: Shorten FK identifiers in add_field and make co…

…nsistent
  • Loading branch information...
andrewgodwin committed Jul 21, 2014
1 parent f57e843 commit 88135a8cf7d587b88e47f1223cf01c7698b52b74
Showing with 41 additions and 14 deletions.
  1. +6 −8 django/db/backends/schema.py
  2. +9 −1 tests/schema/models.py
  3. +26 −5 tests/schema/tests.py
@@ -435,11 +435,7 @@ def add_field(self, model, field):
to_column = field.rel.to._meta.get_field(field.rel.field_name).column
self.deferred_sql.append(
self.sql_create_fk % {
- "name": self.quote_name('%s_refs_%s_%x' % (
- field.column,
- to_column,
- abs(hash((model._meta.db_table, to_table)))
- )),
+ "name": self._create_index_name(model, [field.column], suffix="_fk_%s_%s" % (to_table, to_column)),
"table": self.quote_name(model._meta.db_table),
"column": self.quote_name(field.column),
"to_table": self.quote_name(to_table),
@@ -737,13 +733,15 @@ def _alter_field(self, model, old_field, new_field, old_type, new_type, old_db_p
)
# Does it have a foreign key?
if new_field.rel:
+ to_table = new_field.rel.to._meta.db_table
+ to_column = new_field.rel.get_related_field().column
self.execute(
self.sql_create_fk % {
"table": self.quote_name(model._meta.db_table),
- "name": self._create_index_name(model, [new_field.column], suffix="_fk"),
+ "name": self._create_index_name(model, [new_field.column], suffix="_fk_%s_%s" % (to_table, to_column)),
"column": self.quote_name(new_field.column),
- "to_table": self.quote_name(new_field.rel.to._meta.db_table),
- "to_column": self.quote_name(new_field.rel.get_related_field().column),
+ "to_table": self.quote_name(to_table),
+ "to_column": self.quote_name(to_column),
}
)
# Rebuild FKs that pointed to us if we previously had to drop them
View
@@ -129,8 +129,16 @@ class Meta:
unique_together = ["year", "slug"]
+class AuthorWithEvenLongerName(models.Model):
+ name = models.CharField(max_length=255)
+ height = models.PositiveIntegerField(null=True, blank=True)
+
+ class Meta:
+ apps = new_apps
+
+
class BookWithLongName(models.Model):
- author_foreign_key_with_really_long_field_name = models.ForeignKey(Author)
+ author_foreign_key_with_really_long_field_name = models.ForeignKey(AuthorWithEvenLongerName)
class Meta:
apps = new_apps
View
@@ -9,7 +9,8 @@
from django.db.transaction import atomic
from .models import (Author, AuthorWithM2M, Book, BookWithLongName,
BookWithSlug, BookWithM2M, Tag, TagIndexed, TagM2MTest, TagUniqueRename,
- UniqueTest, Thing, TagThrough, BookWithM2MThrough, AuthorTag, AuthorWithM2MThrough)
+ UniqueTest, Thing, TagThrough, BookWithM2MThrough, AuthorTag, AuthorWithM2MThrough,
+ AuthorWithEvenLongerName)
class SchemaTests(TransactionTestCase):
@@ -26,7 +27,7 @@ class SchemaTests(TransactionTestCase):
models = [
Author, AuthorWithM2M, Book, BookWithLongName, BookWithSlug,
BookWithM2M, Tag, TagIndexed, TagM2MTest, TagUniqueRename, UniqueTest,
- Thing, TagThrough, BookWithM2MThrough
+ Thing, TagThrough, BookWithM2MThrough, AuthorWithEvenLongerName
]
# Utility functions
@@ -846,14 +847,15 @@ class SomeError(Exception):
except SomeError:
self.assertFalse(connection.in_atomic_block)
+ @unittest.skipUnless(connection.features.supports_foreign_keys, "No FK support")
def test_foreign_key_index_long_names_regression(self):
"""
- Regression test for #21497. Only affects databases that supports
- foreign keys.
+ Regression test for #21497.
+ Only affects databases that supports foreign keys.
"""
# Create the table
with connection.schema_editor() as editor:
- editor.create_model(Author)
+ editor.create_model(AuthorWithEvenLongerName)
editor.create_model(BookWithLongName)
# Find the properly shortened column name
column_name = connection.ops.quote_name("author_foreign_key_with_really_long_field_name_id")
@@ -864,6 +866,25 @@ def test_foreign_key_index_long_names_regression(self):
self.get_indexes(BookWithLongName._meta.db_table),
)
+ @unittest.skipUnless(connection.features.supports_foreign_keys, "No FK support")
+ def test_add_foreign_key_long_names(self):
+ """
+ Regression test for #23009.
+ Only affects databases that supports foreign keys.
+ """
+ # Create the initial tables
+ with connection.schema_editor() as editor:
+ editor.create_model(AuthorWithEvenLongerName)
+ editor.create_model(BookWithLongName)
+ # Add a second FK, this would fail due to long ref name before the fix
+ new_field = ForeignKey(AuthorWithEvenLongerName, related_name="something")
+ new_field.set_attributes_from_name("author_other_really_long_named_i_mean_so_long_fk")
+ with connection.schema_editor() as editor:
+ editor.add_field(
+ BookWithLongName,
+ new_field,
+ )
+
def test_creation_deletion_reserved_names(self):
"""
Tries creating a model's table, and then deleting it when it has a

0 comments on commit 88135a8

Please sign in to comment.