authentik.tasks.migrations.0001_initial

  1# Generated by Django 5.1.11 on 2025-06-25 14:50
  2
  3import django.db.models.deletion
  4import django.utils.timezone
  5import pgtrigger.compiler
  6import pgtrigger.migrations
  7import uuid
  8from django.db import migrations, models
  9
 10
 11class Migration(migrations.Migration):
 12
 13    initial = True
 14
 15    dependencies = [
 16        ("authentik_tenants", "0005_tenant_reputation_lower_limit_and_more"),
 17        ("contenttypes", "0002_remove_content_type_name"),
 18    ]
 19
 20    operations = [
 21        migrations.CreateModel(
 22            name="WorkerStatus",
 23            fields=[
 24                ("id", models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
 25                ("hostname", models.TextField()),
 26                ("version", models.TextField()),
 27                ("last_seen", models.DateTimeField(auto_now_add=True)),
 28            ],
 29            options={
 30                "verbose_name": "Worker status",
 31                "verbose_name_plural": "Worker statuses",
 32                "default_permissions": [],
 33            },
 34        ),
 35        migrations.CreateModel(
 36            name="Task",
 37            fields=[
 38                (
 39                    "message_id",
 40                    models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False),
 41                ),
 42                ("queue_name", models.TextField(default="default", help_text="Queue name")),
 43                ("actor_name", models.TextField(help_text="Dramatiq actor name")),
 44                ("message", models.BinaryField(help_text="Message body", null=True)),
 45                (
 46                    "state",
 47                    models.CharField(
 48                        choices=[
 49                            ("queued", "Queued"),
 50                            ("consumed", "Consumed"),
 51                            ("rejected", "Rejected"),
 52                            ("done", "Done"),
 53                        ],
 54                        default="queued",
 55                        help_text="Task status",
 56                    ),
 57                ),
 58                (
 59                    "mtime",
 60                    models.DateTimeField(
 61                        default=django.utils.timezone.now, help_text="Task last modified time"
 62                    ),
 63                ),
 64                ("result", models.BinaryField(help_text="Task result", null=True)),
 65                ("result_expiry", models.DateTimeField(help_text="Result expiry time", null=True)),
 66                ("rel_obj_id", models.TextField(null=True)),
 67                ("_uid", models.TextField(blank=True, null=True)),
 68                ("_messages", models.JSONField(default=list)),
 69                ("_previous_messages", models.JSONField(default=list)),
 70                (
 71                    "aggregated_status",
 72                    models.TextField(
 73                        choices=[
 74                            ("queued", "Queued"),
 75                            ("consumed", "Consumed"),
 76                            ("rejected", "Rejected"),
 77                            ("done", "Done"),
 78                            ("info", "Info"),
 79                            ("warning", "Warning"),
 80                            ("error", "Error"),
 81                        ]
 82                    ),
 83                ),
 84                (
 85                    "rel_obj_content_type",
 86                    models.ForeignKey(
 87                        null=True,
 88                        on_delete=django.db.models.deletion.CASCADE,
 89                        to="contenttypes.contenttype",
 90                    ),
 91                ),
 92                (
 93                    "tenant",
 94                    models.ForeignKey(
 95                        help_text="Tenant this task belongs to",
 96                        on_delete=django.db.models.deletion.CASCADE,
 97                        to="authentik_tenants.tenant",
 98                    ),
 99                ),
100            ],
101            options={
102                "verbose_name": "Task",
103                "verbose_name_plural": "Tasks",
104                "permissions": [("retry_task", "Retry failed task")],
105                "abstract": False,
106                "default_permissions": ("view",),
107                "indexes": [
108                    models.Index(fields=["state", "mtime"], name="authentik_t_state_bb4a31_idx"),
109                    models.Index(
110                        fields=["rel_obj_content_type", "rel_obj_id"],
111                        name="authentik_t_rel_obj_3a177a_idx",
112                    ),
113                ],
114            },
115        ),
116        pgtrigger.migrations.AddTrigger(
117            model_name="task",
118            trigger=pgtrigger.compiler.Trigger(
119                name="notify_enqueueing",
120                sql=pgtrigger.compiler.UpsertTriggerSql(
121                    condition="WHEN (NEW.\"state\" = 'queued')",
122                    constraint="CONSTRAINT",
123                    func="\n                    PERFORM pg_notify(\n                        'authentik.tasks.' || NEW.queue_name || '.enqueue',\n                        NEW.message_id::text\n                    );\n                    RETURN NEW;\n                ",
124                    hash="0a9ee3db61e4d63fd72b31322fbb821706dd8a78",
125                    operation="INSERT OR UPDATE",
126                    pgid="pgtrigger_notify_enqueueing_0bc94",
127                    table="authentik_tasks_task",
128                    timing="DEFERRABLE INITIALLY DEFERRED",
129                    when="AFTER",
130                ),
131            ),
132        ),
133        pgtrigger.migrations.AddTrigger(
134            model_name="task",
135            trigger=pgtrigger.compiler.Trigger(
136                name="update_aggregated_status",
137                sql=pgtrigger.compiler.UpsertTriggerSql(
138                    func="\n                    NEW.aggregated_status := CASE\n                        WHEN NEW.state != 'done' THEN NEW.state\n                        ELSE COALESCE((\n                            SELECT CASE\n                                WHEN bool_or(msg->>'log_level' = 'error') THEN 'error'\n                                WHEN bool_or(msg->>'log_level' = 'warning') THEN 'warning'\n                                WHEN bool_or(msg->>'log_level' = 'info') THEN 'info'\n                                ELSE 'done'\n                            END\n                            FROM jsonb_array_elements(NEW._messages) AS msg\n                        ), 'done')\n                    END;\n\n                    RETURN NEW;\n                ",
139                    hash="ebc09bc08c1624966c0c58a52f243fe25a842058",
140                    operation="INSERT OR UPDATE",
141                    pgid="pgtrigger_update_aggregated_status_f18c4",
142                    table="authentik_tasks_task",
143                    when="BEFORE",
144                ),
145            ),
146        ),
147    ]
class Migration(django.db.migrations.migration.Migration):
 12class Migration(migrations.Migration):
 13
 14    initial = True
 15
 16    dependencies = [
 17        ("authentik_tenants", "0005_tenant_reputation_lower_limit_and_more"),
 18        ("contenttypes", "0002_remove_content_type_name"),
 19    ]
 20
 21    operations = [
 22        migrations.CreateModel(
 23            name="WorkerStatus",
 24            fields=[
 25                ("id", models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
 26                ("hostname", models.TextField()),
 27                ("version", models.TextField()),
 28                ("last_seen", models.DateTimeField(auto_now_add=True)),
 29            ],
 30            options={
 31                "verbose_name": "Worker status",
 32                "verbose_name_plural": "Worker statuses",
 33                "default_permissions": [],
 34            },
 35        ),
 36        migrations.CreateModel(
 37            name="Task",
 38            fields=[
 39                (
 40                    "message_id",
 41                    models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False),
 42                ),
 43                ("queue_name", models.TextField(default="default", help_text="Queue name")),
 44                ("actor_name", models.TextField(help_text="Dramatiq actor name")),
 45                ("message", models.BinaryField(help_text="Message body", null=True)),
 46                (
 47                    "state",
 48                    models.CharField(
 49                        choices=[
 50                            ("queued", "Queued"),
 51                            ("consumed", "Consumed"),
 52                            ("rejected", "Rejected"),
 53                            ("done", "Done"),
 54                        ],
 55                        default="queued",
 56                        help_text="Task status",
 57                    ),
 58                ),
 59                (
 60                    "mtime",
 61                    models.DateTimeField(
 62                        default=django.utils.timezone.now, help_text="Task last modified time"
 63                    ),
 64                ),
 65                ("result", models.BinaryField(help_text="Task result", null=True)),
 66                ("result_expiry", models.DateTimeField(help_text="Result expiry time", null=True)),
 67                ("rel_obj_id", models.TextField(null=True)),
 68                ("_uid", models.TextField(blank=True, null=True)),
 69                ("_messages", models.JSONField(default=list)),
 70                ("_previous_messages", models.JSONField(default=list)),
 71                (
 72                    "aggregated_status",
 73                    models.TextField(
 74                        choices=[
 75                            ("queued", "Queued"),
 76                            ("consumed", "Consumed"),
 77                            ("rejected", "Rejected"),
 78                            ("done", "Done"),
 79                            ("info", "Info"),
 80                            ("warning", "Warning"),
 81                            ("error", "Error"),
 82                        ]
 83                    ),
 84                ),
 85                (
 86                    "rel_obj_content_type",
 87                    models.ForeignKey(
 88                        null=True,
 89                        on_delete=django.db.models.deletion.CASCADE,
 90                        to="contenttypes.contenttype",
 91                    ),
 92                ),
 93                (
 94                    "tenant",
 95                    models.ForeignKey(
 96                        help_text="Tenant this task belongs to",
 97                        on_delete=django.db.models.deletion.CASCADE,
 98                        to="authentik_tenants.tenant",
 99                    ),
100                ),
101            ],
102            options={
103                "verbose_name": "Task",
104                "verbose_name_plural": "Tasks",
105                "permissions": [("retry_task", "Retry failed task")],
106                "abstract": False,
107                "default_permissions": ("view",),
108                "indexes": [
109                    models.Index(fields=["state", "mtime"], name="authentik_t_state_bb4a31_idx"),
110                    models.Index(
111                        fields=["rel_obj_content_type", "rel_obj_id"],
112                        name="authentik_t_rel_obj_3a177a_idx",
113                    ),
114                ],
115            },
116        ),
117        pgtrigger.migrations.AddTrigger(
118            model_name="task",
119            trigger=pgtrigger.compiler.Trigger(
120                name="notify_enqueueing",
121                sql=pgtrigger.compiler.UpsertTriggerSql(
122                    condition="WHEN (NEW.\"state\" = 'queued')",
123                    constraint="CONSTRAINT",
124                    func="\n                    PERFORM pg_notify(\n                        'authentik.tasks.' || NEW.queue_name || '.enqueue',\n                        NEW.message_id::text\n                    );\n                    RETURN NEW;\n                ",
125                    hash="0a9ee3db61e4d63fd72b31322fbb821706dd8a78",
126                    operation="INSERT OR UPDATE",
127                    pgid="pgtrigger_notify_enqueueing_0bc94",
128                    table="authentik_tasks_task",
129                    timing="DEFERRABLE INITIALLY DEFERRED",
130                    when="AFTER",
131                ),
132            ),
133        ),
134        pgtrigger.migrations.AddTrigger(
135            model_name="task",
136            trigger=pgtrigger.compiler.Trigger(
137                name="update_aggregated_status",
138                sql=pgtrigger.compiler.UpsertTriggerSql(
139                    func="\n                    NEW.aggregated_status := CASE\n                        WHEN NEW.state != 'done' THEN NEW.state\n                        ELSE COALESCE((\n                            SELECT CASE\n                                WHEN bool_or(msg->>'log_level' = 'error') THEN 'error'\n                                WHEN bool_or(msg->>'log_level' = 'warning') THEN 'warning'\n                                WHEN bool_or(msg->>'log_level' = 'info') THEN 'info'\n                                ELSE 'done'\n                            END\n                            FROM jsonb_array_elements(NEW._messages) AS msg\n                        ), 'done')\n                    END;\n\n                    RETURN NEW;\n                ",
140                    hash="ebc09bc08c1624966c0c58a52f243fe25a842058",
141                    operation="INSERT OR UPDATE",
142                    pgid="pgtrigger_update_aggregated_status_f18c4",
143                    table="authentik_tasks_task",
144                    when="BEFORE",
145                ),
146            ),
147        ),
148    ]

The base class for all migrations.

Migration files will import this from django.db.migrations.Migration and subclass it as a class called Migration. It will have one or more of the following attributes:

  • operations: A list of Operation instances, probably from django.db.migrations.operations
  • dependencies: A list of tuples of (app_path, migration_name)
  • run_before: A list of tuples of (app_path, migration_name)
  • replaces: A list of migration_names

Note that all migrations come out of migrations and into the Loader or Graph as instances, having been initialized with their app label and name.

initial = True
dependencies = [('authentik_tenants', '0005_tenant_reputation_lower_limit_and_more'), ('contenttypes', '0002_remove_content_type_name')]
operations = [<CreateModel name='WorkerStatus', fields=[('id', <django.db.models.fields.UUIDField>), ('hostname', <django.db.models.fields.TextField>), ('version', <django.db.models.fields.TextField>), ('last_seen', <django.db.models.fields.DateTimeField>)], options={'verbose_name': 'Worker status', 'verbose_name_plural': 'Worker statuses', 'default_permissions': []}>, <CreateModel name='Task', fields=[('message_id', <django.db.models.fields.UUIDField>), ('queue_name', <django.db.models.fields.TextField>), ('actor_name', <django.db.models.fields.TextField>), ('message', <django.db.models.fields.BinaryField>), ('state', <django.db.models.fields.CharField>), ('mtime', <django.db.models.fields.DateTimeField>), ('result', <django.db.models.fields.BinaryField>), ('result_expiry', <django.db.models.fields.DateTimeField>), ('rel_obj_id', <django.db.models.fields.TextField>), ('_uid', <django.db.models.fields.TextField>), ('_messages', <django.db.models.fields.json.JSONField>), ('_previous_messages', <django.db.models.fields.json.JSONField>), ('aggregated_status', <django.db.models.fields.TextField>), ('rel_obj_content_type', <django.db.models.fields.related.ForeignKey>), ('tenant', <django.db.models.fields.related.ForeignKey>)], options={'verbose_name': 'Task', 'verbose_name_plural': 'Tasks', 'permissions': [('retry_task', 'Retry failed task')], 'abstract': False, 'default_permissions': ('view',), 'indexes': [<Index: fields=['state', 'mtime'] name='authentik_t_state_bb4a31_idx'>, <Index: fields=['rel_obj_content_type', 'rel_obj_id'] name='authentik_t_rel_obj_3a177a_idx'>]}>, <AddTrigger model_name='task', trigger=<pgtrigger.compiler.Trigger object>>, <AddTrigger model_name='task', trigger=<pgtrigger.compiler.Trigger object>>]