From b68a2ea04679de0da6a4ef1cb4ed5dddcbcb9458 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Fri, 22 Nov 2024 15:10:24 -0500 Subject: [PATCH] add support for Meta.constraints and Meta.index_together --- django_mongodb/schema.py | 16 +++--- tests/schema_/models.py | 4 ++ tests/schema_/test_embedded_model.py | 78 ++++++++++++++++++++++++++-- 3 files changed, 89 insertions(+), 9 deletions(-) diff --git a/django_mongodb/schema.py b/django_mongodb/schema.py index c605620c..dab1a1fc 100644 --- a/django_mongodb/schema.py +++ b/django_mongodb/schema.py @@ -54,7 +54,9 @@ def _create_model_indexes(self, model, column_prefix="", parent_model=None): self._add_field_unique(parent_model or model, field, column_prefix=column_prefix) # Meta.index_together (RemovedInDjango51Warning) for field_names in model._meta.index_together: - self._add_composed_index(model, field_names) + self._add_composed_index( + model, field_names, column_prefix=column_prefix, parent_model=parent_model + ) # Meta.unique_together if model._meta.unique_together: self.alter_unique_together( @@ -66,7 +68,9 @@ def _create_model_indexes(self, model, column_prefix="", parent_model=None): ) # Meta.constraints for constraint in model._meta.constraints: - self.add_constraint(model, constraint) + self.add_constraint( + model, constraint, column_prefix=column_prefix, parent_model=parent_model + ) # Meta.indexes for index in model._meta.indexes: self.add_index(model, index, column_prefix=column_prefix, parent_model=parent_model) @@ -153,7 +157,7 @@ def remove_field(self, model, field): elif self._field_should_have_unique(field): self._remove_field_unique(model, field) - def alter_index_together(self, model, old_index_together, new_index_together): + def alter_index_together(self, model, old_index_together, new_index_together, column_prefix=""): olds = {tuple(fields) for fields in old_index_together} news = {tuple(fields) for fields in new_index_together} # Deleted indexes @@ -161,7 +165,7 @@ def alter_index_together(self, model, old_index_together, new_index_together): self._remove_composed_index(model, field_names, {"index": True, "unique": False}) # Created indexes for field_names in news.difference(olds): - self._add_composed_index(model, field_names) + self._add_composed_index(model, field_names, column_prefix=column_prefix) def alter_unique_together( self, model, old_unique_together, new_unique_together, column_prefix="", parent_model=None @@ -229,11 +233,11 @@ def add_index( model = parent_model or model self.get_collection(model._meta.db_table).create_indexes([idx]) - def _add_composed_index(self, model, field_names): + def _add_composed_index(self, model, field_names, column_prefix="", parent_model=None): """Add an index on the given list of field_names.""" idx = Index(fields=field_names) idx.set_name_with_model(model) - self.add_index(model, idx) + self.add_index(model, idx, column_prefix=column_prefix, parent_model=parent_model) def _add_field_index(self, model, field, *, column_prefix=""): """Add an index on a field with db_index=True.""" diff --git a/tests/schema_/models.py b/tests/schema_/models.py index 38f12482..6447c118 100644 --- a/tests/schema_/models.py +++ b/tests/schema_/models.py @@ -18,9 +18,11 @@ class Address(models.Model): unique_together_one = models.CharField(max_length=10) unique_together_two = models.CharField(max_length=10) indexed_by_index_one = models.CharField(max_length=10) + unique_constraint_one = models.CharField(max_length=10) class Meta: apps = new_apps + constraints = [models.UniqueConstraint(fields=["unique_constraint_one"], name="unique_one")] indexes = [models.Index(fields=["indexed_by_index_one"])] unique_together = [("unique_together_one", "unique_together_two")] @@ -33,9 +35,11 @@ class Author(models.Model): unique_together_three = models.CharField(max_length=10) unique_together_four = models.CharField(max_length=10) indexed_by_index_two = models.CharField(max_length=10) + unique_constraint_two = models.CharField(max_length=10) class Meta: apps = new_apps + constraints = [models.UniqueConstraint(fields=["unique_constraint_two"], name="unique_two")] indexes = [models.Index(fields=["indexed_by_index_two"])] unique_together = [("unique_together_three", "unique_together_four")] diff --git a/tests/schema_/test_embedded_model.py b/tests/schema_/test_embedded_model.py index 64799069..6189e9d2 100644 --- a/tests/schema_/test_embedded_model.py +++ b/tests/schema_/test_embedded_model.py @@ -1,7 +1,11 @@ import itertools -from django.db import connection -from django.test import TransactionTestCase +from django.db import connection, models +from django.test import TransactionTestCase, ignore_warnings +from django.test.utils import isolate_apps +from django.utils.deprecation import RemovedInDjango51Warning + +from django_mongodb.fields import EmbeddedModelField from .models import Address, Author, Book, new_apps @@ -199,6 +203,54 @@ def test_unique(self): editor.delete_model(Book) self.assertTableNotExists(Author) + @ignore_warnings(category=RemovedInDjango51Warning) + @isolate_apps("schema_") + def test_index_together(self): + """Meta.index_together on an embedded model.""" + + class Address(models.Model): + index_together_one = models.CharField(max_length=10) + index_together_two = models.CharField(max_length=10) + + class Meta: + app_label = "schema" + index_together = [("index_together_one", "index_together_two")] + + class Author(models.Model): + address = EmbeddedModelField(Address) + index_together_three = models.CharField(max_length=10) + index_together_four = models.CharField(max_length=10) + + class Meta: + app_label = "schema" + index_together = [("index_together_three", "index_together_four")] + + class Book(models.Model): + author = EmbeddedModelField(Author) + + class Meta: + app_label = "schema" + + with connection.schema_editor() as editor: + editor.create_model(Book) + self.assertTableExists(Book) + # Embedded uniques are created. + self.assertEqual( + self.get_constraints_for_columns( + Book, ["author.address.index_together_one", "author.address.index_together_two"] + ), + ["schema_addr_index_t_a0305a_idx"], + ) + self.assertEqual( + self.get_constraints_for_columns( + Book, + ["author.index_together_three", "author.index_together_four"], + ), + ["schema_auth_index_t_65817b_idx"], + ) + editor.delete_model(Author) + self.assertTableNotExists(Author) + def test_unique_together(self): """Meta.unique_together on an embedded model.""" with connection.schema_editor() as editor: @@ -225,7 +277,7 @@ def test_unique_together(self): editor.delete_model(Author) self.assertTableNotExists(Author) - def test_index(self): + def test_indexes(self): """Meta.indexes on an embedded model.""" with connection.schema_editor() as editor: editor.create_model(Book) @@ -244,3 +296,23 @@ def test_index(self): ) editor.delete_model(Author) self.assertTableNotExists(Author) + + def test_constraints(self): + """Meta.constraints on an embedded model.""" + with connection.schema_editor() as editor: + editor.create_model(Book) + self.assertTableExists(Book) + # Embedded uniques are created. + self.assertEqual( + self.get_constraints_for_columns(Book, ["author.unique_constraint_two"]), + ["unique_two"], + ) + self.assertEqual( + self.get_constraints_for_columns( + Book, + ["author.address.unique_constraint_one"], + ), + ["unique_one"], + ) + editor.delete_model(Author) + self.assertTableNotExists(Author)