Skip to content

Commit

Permalink
add support for Meta.constraints and Meta.index_together
Browse files Browse the repository at this point in the history
  • Loading branch information
timgraham committed Dec 30, 2024
1 parent 5743eb9 commit b68a2ea
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 9 deletions.
16 changes: 10 additions & 6 deletions django_mongodb/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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)
Expand Down Expand Up @@ -153,15 +157,15 @@ 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
for field_names in olds.difference(news):
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
Expand Down Expand Up @@ -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."""
Expand Down
4 changes: 4 additions & 0 deletions tests/schema_/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")]

Expand All @@ -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")]

Expand Down
78 changes: 75 additions & 3 deletions tests/schema_/test_embedded_model.py
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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:
Expand All @@ -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)
Expand All @@ -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)

0 comments on commit b68a2ea

Please sign in to comment.