Browse Source

:sparkles: ref(aci): make detector project fk non nullable (#85240)

this pr makes the project FK on detectors non nullable. this was an
artifact from when we switched from having detectors org-scoped to
project scoped.

redash queries on [us](https://redash.getsentry.net/queries/8357/) and
[de](https://redash.de.getsentry.net/queries/115/) returns 0 detectors
with a null FK, so this should be safe to do.

also there are only 2 detectors in us and 0 in de, so we don't need to
be post deploy

Query: 
```sql
select count(1) from workflow_engine_detector where project_id is null
```
Raj Joshi 3 weeks ago
parent
commit
9bc78efec9

+ 1 - 1
migrations_lockfile.txt

@@ -23,4 +23,4 @@ tempest: 0001_create_tempest_credentials_model
 
 uptime: 0025_uptime_migrate_constraint
 
-workflow_engine: 0030_allow_blank_workflow_owner_fks
+workflow_engine: 0031_make_detector_project_non_nullable

+ 1 - 3
src/sentry/workflow_engine/endpoints/validators/error_detector.py

@@ -52,9 +52,7 @@ class ErrorDetectorValidator(BaseDetectorTypeValidator):
                 config={},
             )
 
-            project: Project | None = detector.project
-            if not project:
-                raise serializers.ValidationError("Error detector must have a project")
+            project: Project = detector.project
 
             # update configs, which are project options. continue using them
             for config in validated_data:

+ 38 - 0
src/sentry/workflow_engine/migrations/0031_make_detector_project_non_nullable.py

@@ -0,0 +1,38 @@
+# Generated by Django 5.1.5 on 2025-02-18 17:50
+
+import django.db.models.deletion
+from django.db import migrations
+
+import sentry.db.models.fields.foreignkey
+from sentry.new_migrations.migrations import CheckedMigration
+
+
+class Migration(CheckedMigration):
+    # This flag is used to mark that a migration shouldn't be automatically run in production.
+    # This should only be used for operations where it's safe to run the migration after your
+    # code has deployed. So this should not be used for most operations that alter the schema
+    # of a table.
+    # Here are some things that make sense to mark as post deployment:
+    # - Large data migrations. Typically we want these to be run manually so that they can be
+    #   monitored and not block the deploy for a long period of time while they run.
+    # - Adding indexes to large tables. Since this can take a long time, we'd generally prefer to
+    #   run this outside deployments so that we don't block them. Note that while adding an index
+    #   is a schema change, it's completely safe to run the operation after the code has deployed.
+    # Once deployed, run these manually via: https://develop.sentry.dev/database-migrations/#migration-deployment
+
+    is_post_deployment = False
+
+    dependencies = [
+        ("sentry", "0832_make_grouphash_metadata_date_added_nullable"),
+        ("workflow_engine", "0030_allow_blank_workflow_owner_fks"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="detector",
+            name="project",
+            field=sentry.db.models.fields.foreignkey.FlexibleForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="sentry.project"
+            ),
+        ),
+    ]

+ 1 - 1
src/sentry/workflow_engine/models/detector.py

@@ -31,7 +31,7 @@ logger = logging.getLogger(__name__)
 class Detector(DefaultFieldsModel, OwnerModel, JSONConfigBase):
     __relocation_scope__ = RelocationScope.Organization
 
-    project = FlexibleForeignKey("sentry.Project", on_delete=models.CASCADE, null=True)
+    project = FlexibleForeignKey("sentry.Project", on_delete=models.CASCADE)
     name = models.CharField(max_length=200)
 
     # The data sources that the detector is watching