Skip to content

Commit 63f441c

Browse files
authored
fix: delete data connector when its slug is deleted (#865)
Closes #859.
1 parent 5e2ce9e commit 63f441c

1 file changed

Lines changed: 50 additions & 0 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
"""Cleanup data connector when slug is removed
2+
3+
Revision ID: f4ad62b7b323
4+
Revises: dcb9648c3c15
5+
Create Date: 2025-05-19 07:15:11.989650
6+
7+
"""
8+
9+
import sqlalchemy as sa
10+
from alembic import op
11+
12+
# revision identifiers, used by Alembic.
13+
revision = "f4ad62b7b323"
14+
down_revision = "dcb9648c3c15"
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade() -> None:
20+
"""Register a trigger and function to remove a data connector when its slug is removed.
21+
22+
This is necessary because we only have a foreign key on the slugs table pointing to Data Connectors, so
23+
we remove slugs when a data connector is removed. But we also want to remove projects when a slug is removed
24+
because this can occur when you delete a group and all data connectors within the group should also be deleted."""
25+
op.execute(sa.text("LOCK TABLE common.entity_slugs IN EXCLUSIVE MODE"))
26+
op.execute(sa.text("LOCK TABLE storage.data_connectors IN EXCLUSIVE MODE"))
27+
# NOTE: OLD variable holds the name of the row that is being deleted (i.e. the trigger)
28+
op.execute("""CREATE OR REPLACE FUNCTION delete_data_connector_after_slug_deletion()
29+
RETURNS TRIGGER AS
30+
$$
31+
BEGIN
32+
DELETE FROM storage.data_connectors WHERE data_connectors.id = OLD.data_connector_id;
33+
RETURN OLD;
34+
END;
35+
$$
36+
LANGUAGE plpgsql;""")
37+
op.execute("""CREATE OR REPLACE TRIGGER delete_data_connector_after_slug_deletion
38+
AFTER DELETE ON common.entity_slugs
39+
FOR EACH ROW
40+
EXECUTE FUNCTION delete_data_connector_after_slug_deletion();""")
41+
# NOTE: Here we cleanup the data connectors which have neither a namespaced slug nor a global slug.
42+
op.execute("""DELETE FROM storage.data_connectors
43+
WHERE data_connectors.id NOT IN (
44+
SELECT entity_slugs.data_connector_id FROM common.entity_slugs WHERE entity_slugs.data_connector_id IS NOT NULL
45+
) AND data_connectors.global_slug IS NULL""")
46+
47+
48+
def downgrade() -> None:
49+
op.execute("DROP TRIGGER IF EXISTS delete_data_connector_after_slug_deletion ON storage.data_connectors CASCADE;")
50+
op.execute("DROP FUNCTION IF EXISTS delete_data_connector_after_slug_deletion CASCADE;")

0 commit comments

Comments
 (0)