Repository: PrefectHQ/prefect

Issue:
Delete flow run inputs when the corresponding flow run is deleted
When the `FlowRunInput` model was created the flow run wasn't created as a foreign key so deletes do not cascade down to the input table. We should rectify this by changing the column to be a FK with cascading deletes.


Discussion:

Resolving patch:
diff --git a/src/prefect/server/database/migrations/versions/postgresql/2023_12_07_121416_7c453555d3a5_make_flowruninput_flow_run_id_a_foreign_.py b/src/prefect/server/database/migrations/versions/postgresql/2023_12_07_121416_7c453555d3a5_make_flowruninput_flow_run_id_a_foreign_.py
new file mode 100644
--- /dev/null
+++ b/src/prefect/server/database/migrations/versions/postgresql/2023_12_07_121416_7c453555d3a5_make_flowruninput_flow_run_id_a_foreign_.py
@@ -0,0 +1,33 @@
+"""Make `FlowRunInput.flow_run_id` a foreign key to `flow_run`
+
+Revision ID: 7c453555d3a5
+Revises: 733ca1903976
+Create Date: 2023-12-07 12:14:16.744743
+
+"""
+from alembic import op
+
+# revision identifiers, used by Alembic.
+revision = "7c453555d3a5"
+down_revision = "733ca1903976"
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    op.create_foreign_key(
+        op.f("fk_flow_run_input__flow_run_id__flow_run"),
+        "flow_run_input",
+        "flow_run",
+        ["flow_run_id"],
+        ["id"],
+        ondelete="cascade",
+    )
+
+
+def downgrade():
+    op.drop_constraint(
+        op.f("fk_flow_run_input__flow_run_id__flow_run"),
+        "flow_run_input",
+        type_="foreignkey",
+    )
diff --git a/src/prefect/server/database/migrations/versions/sqlite/2023_12_07_121624_35659cc49969_make_flowruninput_flow_run_id_a_foreign_.py b/src/prefect/server/database/migrations/versions/sqlite/2023_12_07_121624_35659cc49969_make_flowruninput_flow_run_id_a_foreign_.py
new file mode 100644
--- /dev/null
+++ b/src/prefect/server/database/migrations/versions/sqlite/2023_12_07_121624_35659cc49969_make_flowruninput_flow_run_id_a_foreign_.py
@@ -0,0 +1,32 @@
+"""Make `FlowRunInput.flow_run_id` a foreign key to `flow_run`
+
+Revision ID: 35659cc49969
+Revises: a299308852a7
+Create Date: 2023-12-07 12:16:24.287059
+
+"""
+from alembic import op
+
+# revision identifiers, used by Alembic.
+revision = "35659cc49969"
+down_revision = "a299308852a7"
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    with op.batch_alter_table("flow_run_input", schema=None) as batch_op:
+        batch_op.create_foreign_key(
+            batch_op.f("fk_flow_run_input__flow_run_id__flow_run"),
+            "flow_run",
+            ["flow_run_id"],
+            ["id"],
+            ondelete="cascade",
+        )
+
+
+def downgrade():
+    with op.batch_alter_table("flow_run_input", schema=None) as batch_op:
+        batch_op.drop_constraint(
+            batch_op.f("fk_flow_run_input__flow_run_id__flow_run"), type_="foreignkey"
+        )
diff --git a/src/prefect/server/database/orm_models.py b/src/prefect/server/database/orm_models.py
--- a/src/prefect/server/database/orm_models.py
+++ b/src/prefect/server/database/orm_models.py
@@ -1344,8 +1344,7 @@ class ORMFlowRunInput:
     @declared_attr
     def flow_run_id(cls):
         return sa.Column(
-            UUID(),
-            nullable=False,
+            UUID(), sa.ForeignKey("flow_run.id", ondelete="cascade"), nullable=False
         )
 
     key = sa.Column(sa.String, nullable=False)


Test patch: