Browse Source

feat(migrations): Prevent new migrations from using `RunSQL` (#81003)

This adds in `allow_run_sql` to our `CheckedMigration` baseclass. We
want to prevent the use of `RunSQL` in most cases going forward, since
our migration safety framework doesn't know how to parse sql to ensure
safety.

Our main uses for this in the past were:
- Adding new columns with a default. We now can do this within the
framework by using `db_default` instead of `default`.
- Deleting columns/tables. Since we have to remove from state, deploy,
then delete we have to use raw sql to remove them from Postgres. I'll
follow this up with a pr to provide ways to handle these deletions
within our framework.
Dan Fuller 3 months ago
parent
commit
64c5f94db6

+ 0 - 0
fixtures/safe_migrations_apps/bad_flow_run_sql_disabled_app/__init__.py


+ 16 - 0
fixtures/safe_migrations_apps/bad_flow_run_sql_disabled_app/migrations/0001_initial.py

@@ -0,0 +1,16 @@
+# Generated by Django 3.1 on 2019-09-22 21:47
+
+from django.db import migrations
+
+from sentry.new_migrations.migrations import CheckedMigration
+
+
+class Migration(CheckedMigration):
+
+    initial = True
+
+    dependencies = []
+
+    allow_run_sql = False
+
+    operations = [migrations.RunSQL("select 1;")]

+ 0 - 0
fixtures/safe_migrations_apps/bad_flow_run_sql_disabled_app/migrations/__init__.py


+ 5 - 0
fixtures/safe_migrations_apps/bad_flow_run_sql_disabled_app/models.py

@@ -0,0 +1,5 @@
+from django.db import models
+
+
+class TestTable(models.Model):
+    field = models.IntegerField(default=0, null=False)

+ 3 - 10
fixtures/safe_migrations_apps/good_flow_delete_model_state_app/migrations/0002_delete_model_state.py

@@ -1,8 +1,7 @@
 # Generated by Django 3.1 on 2019-09-22 21:47
-
-from django.db import migrations
-
 from sentry.new_migrations.migrations import CheckedMigration
+from sentry.new_migrations.monkey.models import SafeDeleteModel
+from sentry.new_migrations.monkey.state import DeletionAction
 
 
 class Migration(CheckedMigration):
@@ -12,11 +11,5 @@ class Migration(CheckedMigration):
     ]
 
     operations = [
-        migrations.SeparateDatabaseAndState(
-            state_operations=[
-                migrations.DeleteModel(
-                    name="TestTable",
-                ),
-            ]
-        )
+        SafeDeleteModel(name="TestTable", deletion_action=DeletionAction.MOVE_TO_PENDING),
     ]

+ 4 - 5
fixtures/safe_migrations_apps/good_flow_delete_model_state_app/migrations/0003_delete_table.py

@@ -1,16 +1,15 @@
 # Generated by Django 3.1 on 2019-09-22 21:47
-
-from django.db import migrations
-
 from sentry.new_migrations.migrations import CheckedMigration
+from sentry.new_migrations.monkey.models import SafeDeleteModel
+from sentry.new_migrations.monkey.state import DeletionAction
 
 
 class Migration(CheckedMigration):
 
     dependencies = [
-        ("good_flow_delete_model_state_app", "0001_initial"),
+        ("good_flow_delete_model_state_app", "0002_delete_model_state"),
     ]
 
     operations = [
-        migrations.RunSQL('DROP TABLE "good_flow_delete_model_state_app_testtable";'),
+        SafeDeleteModel(name="TestTable", deletion_action=DeletionAction.DELETE),
     ]

+ 0 - 0
fixtures/safe_migrations_apps/good_flow_run_sql_enabled_app/__init__.py


+ 16 - 0
fixtures/safe_migrations_apps/good_flow_run_sql_enabled_app/migrations/0001_initial.py

@@ -0,0 +1,16 @@
+# Generated by Django 3.1 on 2019-09-22 21:47
+
+from django.db import migrations
+
+from sentry.new_migrations.migrations import CheckedMigration
+
+
+class Migration(CheckedMigration):
+
+    initial = True
+
+    dependencies = []
+
+    allow_run_sql = True
+
+    operations = [migrations.RunSQL("select 1;")]

+ 0 - 0
fixtures/safe_migrations_apps/good_flow_run_sql_enabled_app/migrations/__init__.py


+ 5 - 0
fixtures/safe_migrations_apps/good_flow_run_sql_enabled_app/models.py

@@ -0,0 +1,5 @@
+from django.db import models
+
+
+class TestTable(models.Model):
+    field = models.IntegerField(default=0, null=False)

Some files were not shown because too many files changed in this diff