diff --git a/tests/_utils/setup.sql b/tests/_utils/setup.sql index c2e617141bf5..1debfc671fa7 100644 --- a/tests/_utils/setup.sql +++ b/tests/_utils/setup.sql @@ -468,3 +468,40 @@ CREATE TABLE `multiple_database_book_person` ( KEY (`book_id`), KEY (`person_id`) ); + +-- aggregation_regress +CREATE TABLE `aggregation_regress_author_friend` ( + `from_author_id` BIGINT NOT NULL, + `to_author_id` BIGINT NOT NULL, + SHARD KEY (`from_author_id`), + UNIQUE KEY (`from_author_id`, `to_author_id`), + KEY (`from_author_id`), + KEY (`to_author_id`) +); + +CREATE TABLE `aggregation_regress_book_author` ( + `book_id` BIGINT NOT NULL, + `author_id` BIGINT NOT NULL, + SHARD KEY (`book_id`), + UNIQUE KEY (`book_id`,`author_id`), + KEY (`book_id`), + KEY (`author_id`) +); + +CREATE TABLE `aggregation_regress_store_book` ( + `store_id` BIGINT NOT NULL, + `book_id` BIGINT NOT NULL, + SHARD KEY (`store_id`), + UNIQUE KEY (`store_id`,`book_id`), + KEY (`store_id`), + KEY (`book_id`) +); + +CREATE TABLE `aggregation_regress_recipe_authorproxy` ( + `recipe_id` BIGINT NOT NULL, + `authorproxy_id` BIGINT NOT NULL, + SHARD KEY (`recipe_id`), + UNIQUE KEY (`recipe_id`, `authorproxy_id`), + KEY (`recipe_id`), + KEY (`authorproxy_id`) +); \ No newline at end of file diff --git a/tests/aggregation_regress/models.py b/tests/aggregation_regress/models.py index edf0e89a9da0..f34676857a9a 100644 --- a/tests/aggregation_regress/models.py +++ b/tests/aggregation_regress/models.py @@ -2,11 +2,22 @@ from django.contrib.contenttypes.models import ContentType from django.db import models +from django_singlestore.schema import ModelStorageManager + class Author(models.Model): name = models.CharField(max_length=100) age = models.IntegerField() - friends = models.ManyToManyField("self", blank=True) + friends = models.ManyToManyField("Author", blank=True, through="AuthorFriend") + + +class AuthorFriend(models.Model): + from_author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name="from_author") + to_author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name="to_author") + + class Meta: + unique_together = (('from_author', 'to_author'),) + db_table = "aggregation_regress_author_friend" class Publisher(models.Model): @@ -27,7 +38,7 @@ class Book(models.Model): pages = models.IntegerField() rating = models.FloatField() price = models.DecimalField(decimal_places=2, max_digits=6) - authors = models.ManyToManyField(Author) + authors = models.ManyToManyField(Author, through="BookAuthor") contact = models.ForeignKey(Author, models.CASCADE, related_name="book_contact_set") publisher = models.ForeignKey(Publisher, models.CASCADE) pubdate = models.DateField() @@ -35,20 +46,39 @@ class Book(models.Model): class Meta: ordering = ("name",) + +class BookAuthor(models.Model): + book = models.ForeignKey(Book, on_delete=models.CASCADE) + author = models.ForeignKey(Author, on_delete=models.CASCADE) + + class Meta: + unique_together = (('book', 'author'),) + db_table = "aggregation_regress_book_author" class Store(models.Model): name = models.CharField(max_length=255) - books = models.ManyToManyField(Book) + books = models.ManyToManyField(Book, through="StoreBook") original_opening = models.DateTimeField() friday_night_closing = models.TimeField() +class StoreBook(models.Model): + store = models.ForeignKey(Store, on_delete=models.CASCADE) + book = models.ForeignKey(Book, on_delete=models.CASCADE) + + class Meta: + unique_together = (('store', 'book'),) + db_table = "aggregation_regress_store_book" + class Entries(models.Model): EntryID = models.AutoField(primary_key=True, db_column="Entry ID") Entry = models.CharField(unique=True, max_length=50) Exclude = models.BooleanField(default=False) + objects = ModelStorageManager("ROWSTORE REFERENCE") + + class Clues(models.Model): ID = models.AutoField(primary_key=True) @@ -99,7 +129,16 @@ class Meta: class Recipe(models.Model): name = models.CharField(max_length=20) author = models.ForeignKey(AuthorProxy, models.CASCADE) - tasters = models.ManyToManyField(AuthorProxy, related_name="recipes") + tasters = models.ManyToManyField("AuthorProxy", related_name="recipes", through="RecipeAuthorProxy") + + +class RecipeAuthorProxy(models.Model): + recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE) + authorproxy = models.ForeignKey(AuthorProxy, on_delete=models.CASCADE) + + class Meta: + unique_together = (('recipe', 'authorproxy'),) + db_table = "aggregation_regress_recipe_authorproxy" class RecipeProxy(Recipe): diff --git a/tests/aggregation_regress/tests.py b/tests/aggregation_regress/tests.py index bfb3919b2370..50fb034a0700 100644 --- a/tests/aggregation_regress/tests.py +++ b/tests/aggregation_regress/tests.py @@ -596,9 +596,9 @@ def test_decimal_aggregate_annotation_filter(self): def test_field_error(self): # Bad field requests in aggregates are caught and reported msg = ( - "Cannot resolve keyword 'foo' into field. Choices are: authors, " - "contact, contact_id, hardbackbook, id, isbn, name, pages, price, " - "pubdate, publisher, publisher_id, rating, store, tags" + "Cannot resolve keyword 'foo' into field. Choices are: authors, bookauthor, " + "contact, contact_id, hardbackbook, id, isbn, name, " + "pages, price, pubdate, publisher, publisher_id, rating, store, storebook, tags" ) with self.assertRaisesMessage(FieldError, msg): Book.objects.aggregate(num_authors=Count("foo")) @@ -607,9 +607,9 @@ def test_field_error(self): Book.objects.annotate(num_authors=Count("foo")) msg = ( - "Cannot resolve keyword 'foo' into field. Choices are: authors, " + "Cannot resolve keyword 'foo' into field. Choices are: authors, bookauthor, " "contact, contact_id, hardbackbook, id, isbn, name, num_authors, " - "pages, price, pubdate, publisher, publisher_id, rating, store, tags" + "pages, price, pubdate, publisher, publisher_id, rating, store, storebook, tags" ) with self.assertRaisesMessage(FieldError, msg): Book.objects.annotate(num_authors=Count("authors__id")).aggregate(