diff --git a/activities/migrations/0016_index_together_migration.py b/activities/migrations/0016_index_together_migration.py new file mode 100644 index 0000000..6238d85 --- /dev/null +++ b/activities/migrations/0016_index_together_migration.py @@ -0,0 +1,92 @@ +# Generated by Django 4.2.1 on 2023-05-13 17:29 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("activities", "0015_alter_postinteraction_type"), + ] + + operations = [ + migrations.RenameIndex( + model_name="emoji", + new_name="activities__state_r_aa72ec_idx", + old_fields=("state_ready", "state_locked_until", "state"), + ), + migrations.RenameIndex( + model_name="fanout", + new_name="activities__state_r_aae3b4_idx", + old_fields=("state_ready", "state_locked_until", "state"), + ), + migrations.RenameIndex( + model_name="hashtag", + new_name="activities__state_r_5703be_idx", + old_fields=("state_ready", "state_locked_until", "state"), + ), + migrations.RenameIndex( + model_name="post", + new_name="activities__state_r_b8f1ff_idx", + old_fields=("state_ready", "state_locked_until", "state"), + ), + migrations.RenameIndex( + model_name="postattachment", + new_name="activities__state_r_4e981c_idx", + old_fields=("state_ready", "state_locked_until", "state"), + ), + migrations.RenameIndex( + model_name="postinteraction", + new_name="activities__state_r_981d8c_idx", + old_fields=("state_ready", "state_locked_until", "state"), + ), + migrations.RenameIndex( + model_name="postinteraction", + new_name="activities__type_75d2e4_idx", + old_fields=("type", "identity", "post"), + ), + migrations.RenameIndex( + model_name="timelineevent", + new_name="activities__identit_0b93c3_idx", + old_fields=("identity", "type", "subject_post", "subject_identity"), + ), + migrations.RenameIndex( + model_name="timelineevent", + new_name="activities__identit_cc2290_idx", + old_fields=("identity", "type", "subject_identity"), + ), + migrations.RenameIndex( + model_name="timelineevent", + new_name="activities__identit_872fbb_idx", + old_fields=("identity", "created"), + ), + migrations.AddIndex( + model_name="emoji", + index=models.Index( + fields=["state", "state_attempted"], name="ix_emoji_state_attempted" + ), + ), + migrations.AddIndex( + model_name="emoji", + index=models.Index( + condition=models.Q(("state_locked_until__isnull", False)), + fields=["state_locked_until", "state"], + name="ix_emoji_state_locked", + ), + ), + migrations.AddIndex( + model_name="postinteraction", + index=models.Index( + fields=["state", "state_attempted"], + name="ix_postinterac_state_attempted", + ), + ), + migrations.AddIndex( + model_name="postinteraction", + index=models.Index( + condition=models.Q(("state_locked_until__isnull", False)), + fields=["state_locked_until", "state"], + name="ix_postinterac_state_locked", + ), + ), + ] diff --git a/activities/models/emoji.py b/activities/models/emoji.py index 6775bcd..57d8707 100644 --- a/activities/models/emoji.py +++ b/activities/models/emoji.py @@ -86,7 +86,6 @@ class EmojiManager(models.Manager): class Emoji(StatorModel): - # Normalized Emoji without the ':' shortcode = models.SlugField(max_length=100, db_index=True) @@ -128,7 +127,7 @@ class Emoji(StatorModel): class Meta: unique_together = ("domain", "shortcode") - index_together = StatorModel.Meta.index_together + indexes = StatorModel.Meta.indexes class urls(urlman.Urls): admin = "/admin/emoji/" diff --git a/activities/models/post.py b/activities/models/post.py index 88fba62..045233e 100644 --- a/activities/models/post.py +++ b/activities/models/post.py @@ -325,8 +325,7 @@ class Post(StatorModel): fields=["visibility", "local", "created"], name="ix_post_local_public_created", ), - ] - index_together = StatorModel.Meta.index_together + ] + StatorModel.Meta.indexes class urls(urlman.Urls): view = "{self.author.urls.view}posts/{self.id}/" diff --git a/activities/models/post_interaction.py b/activities/models/post_interaction.py index eb8d684..953b2f3 100644 --- a/activities/models/post_interaction.py +++ b/activities/models/post_interaction.py @@ -179,9 +179,9 @@ class PostInteraction(StatorModel): updated = models.DateTimeField(auto_now=True) class Meta: - index_together = [ - ["type", "identity", "post"] - ] + StatorModel.Meta.index_together + indexes = [ + models.Index(fields=["type", "identity", "post"]) + ] + StatorModel.Meta.indexes ### Display helpers ### diff --git a/activities/models/timeline_event.py b/activities/models/timeline_event.py index 2f62d19..33976b8 100644 --- a/activities/models/timeline_event.py +++ b/activities/models/timeline_event.py @@ -59,11 +59,13 @@ class TimelineEvent(models.Model): created = models.DateTimeField(auto_now_add=True) class Meta: - index_together = [ + indexes = [ # This relies on a DB that can use left subsets of indexes - ("identity", "type", "subject_post", "subject_identity"), - ("identity", "type", "subject_identity"), - ("identity", "created"), + models.Index( + fields=["identity", "type", "subject_post", "subject_identity"] + ), + models.Index(fields=["identity", "type", "subject_identity"]), + models.Index(fields=["identity", "created"]), ] ### Alternate constructors ### diff --git a/stator/models.py b/stator/models.py index 101a4ff..ddb8547 100644 --- a/stator/models.py +++ b/stator/models.py @@ -102,10 +102,7 @@ class StatorModel(models.Model): class Meta: abstract = True - index_together = [("state_ready", "state_locked_until", "state")] - # Need this empty indexes to ensure child Models have a Meta.indexes - # that will look to add indexes (that we inject with class_prepared) - indexes: list = [] + indexes = [models.Index(fields=["state_ready", "state_locked_until", "state"])] def __init_subclass__(cls) -> None: if cls is not StatorModel: @@ -194,13 +191,11 @@ class StatorModel(models.Model): """ Returns how many instances are "queued" """ - return await ( - cls.objects.filter( - state_locked_until__isnull=True, - state_ready=True, - state__in=cls.state_graph.automatic_states, - ).acount() - ) + return await cls.objects.filter( + state_locked_until__isnull=True, + state_ready=True, + state__in=cls.state_graph.automatic_states, + ).acount() @classmethod async def atransition_clean_locks(cls): diff --git a/users/migrations/0018_index_together_migration.py b/users/migrations/0018_index_together_migration.py new file mode 100644 index 0000000..cd9c872 --- /dev/null +++ b/users/migrations/0018_index_together_migration.py @@ -0,0 +1,90 @@ +# Generated by Django 4.2.1 on 2023-05-13 17:29 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("users", "0017_identity_featured_collection_uri"), + ] + + operations = [ + migrations.RenameIndex( + model_name="block", + new_name="users_block_state_r_e016a2_idx", + old_fields=("state_ready", "state_locked_until", "state"), + ), + migrations.RenameIndex( + model_name="domain", + new_name="users_domai_state_r_42b328_idx", + old_fields=("state_ready", "state_locked_until", "state"), + ), + migrations.RenameIndex( + model_name="follow", + new_name="users_follo_state_r_d1dbc2_idx", + old_fields=("state_ready", "state_locked_until", "state"), + ), + migrations.RenameIndex( + model_name="identity", + new_name="users_ident_state_r_6fdeee_idx", + old_fields=("state_ready", "state_locked_until", "state"), + ), + migrations.RenameIndex( + model_name="inboxmessage", + new_name="users_inbox_state_r_00fce2_idx", + old_fields=("state_ready", "state_locked_until", "state"), + ), + migrations.RenameIndex( + model_name="passwordreset", + new_name="users_passw_state_r_f54f10_idx", + old_fields=("state_ready", "state_locked_until", "state"), + ), + migrations.RenameIndex( + model_name="report", + new_name="users_repor_state_r_345b80_idx", + old_fields=("state_ready", "state_locked_until", "state"), + ), + migrations.AddIndex( + model_name="block", + index=models.Index( + fields=["state", "state_attempted"], name="ix_block_state_attempted" + ), + ), + migrations.AddIndex( + model_name="block", + index=models.Index( + condition=models.Q(("state_locked_until__isnull", False)), + fields=["state_locked_until", "state"], + name="ix_block_state_locked", + ), + ), + migrations.AddIndex( + model_name="follow", + index=models.Index( + fields=["state", "state_attempted"], name="ix_follow_state_attempted" + ), + ), + migrations.AddIndex( + model_name="follow", + index=models.Index( + condition=models.Q(("state_locked_until__isnull", False)), + fields=["state_locked_until", "state"], + name="ix_follow_state_locked", + ), + ), + migrations.AddIndex( + model_name="identity", + index=models.Index( + fields=["state", "state_attempted"], name="ix_identity_state_attempted" + ), + ), + migrations.AddIndex( + model_name="identity", + index=models.Index( + condition=models.Q(("state_locked_until__isnull", False)), + fields=["state_locked_until", "state"], + name="ix_identity_state_locked", + ), + ), + ] diff --git a/users/models/block.py b/users/models/block.py index f941316..3ede7b8 100644 --- a/users/models/block.py +++ b/users/models/block.py @@ -136,7 +136,7 @@ class Block(StatorModel): class Meta: unique_together = [("source", "target", "mute")] - index_together = StatorModel.Meta.index_together + indexes = StatorModel.Meta.indexes def __str__(self): return f"#{self.id}: {self.source} blocks {self.target}" diff --git a/users/models/follow.py b/users/models/follow.py index 4fb692a..e044481 100644 --- a/users/models/follow.py +++ b/users/models/follow.py @@ -146,7 +146,7 @@ class Follow(StatorModel): class Meta: unique_together = [("source", "target")] - index_together = StatorModel.Meta.index_together + indexes = StatorModel.Meta.indexes def __str__(self): return f"#{self.id}: {self.source} → {self.target}" diff --git a/users/models/identity.py b/users/models/identity.py index ee46b40..c16629f 100644 --- a/users/models/identity.py +++ b/users/models/identity.py @@ -227,7 +227,7 @@ class Identity(StatorModel): class Meta: verbose_name_plural = "identities" unique_together = [("username", "domain")] - index_together = StatorModel.Meta.index_together + indexes = StatorModel.Meta.indexes class urls(urlman.Urls): view = "/@{self.username}@{self.domain_id}/"