Skip to content

Conversation

@armenzg
Copy link
Member

@armenzg armenzg commented Oct 31, 2025

When deleting a GroupHistory record, Django would CASCADE to all records that reference it via prev_history, which can create circular dependency loops.

We do not use prev_history at all, thus, we can remove it.

Fixes SENTRY-3WN8 and SENTRY-3WKX.

When deleting a GroupHistory record, Django would CASCADE to all records that reference it via `prev_history`, which can create circular dependency loops.

We do not use `prev_history` at all, thus, we can remove it.

Fixes [SENTRY-3WN8](https://sentry.sentry.io/issues/6619377437/) and [SENTRY-3WKX](https://sentry.sentry.io/issues/6618890707/).
@armenzg armenzg self-assigned this Oct 31, 2025
@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Oct 31, 2025
@armenzg armenzg marked this pull request as ready for review October 31, 2025 12:48
@armenzg armenzg requested review from a team as code owners October 31, 2025 12:48
@armenzg armenzg requested a review from markstory October 31, 2025 12:48
@codecov
Copy link

codecov bot commented Oct 31, 2025

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
40434 2 40432 242
View the top 3 failed test(s) by shortest run time
tests.sentry.monitors.migrations.test_0009_backfill_monitor_detectors.BackfillMonitorDetectorsTest::test
Stack Traces | 0.002s run time
#x1B[1m#x1B[31m.venv/lib/python3.13....../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13....../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.../site-packages/pytest_django/fixtures.py#x1B[0m:144: in django_db_setup
    db_cfg = setup_databases(
#x1B[1m#x1B[31m.venv/lib/python3.13.../django/test/utils.py#x1B[0m:204: in setup_databases
    connection.creation.create_test_db(
#x1B[1m#x1B[31m.venv/lib/python3.13.../backends/base/creation.py#x1B[0m:78: in create_test_db
    call_command(
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/__init__.py#x1B[0m:194: in call_command
    return command.execute(*args, **defaults)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:460: in execute
    output = self.handle(*args, **options)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:107: in wrapper
    res = handle_func(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../management/commands/migrate.py#x1B[0m:353: in handle
    post_migrate_state = executor.migrate(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:135: in migrate
    state = self._migrate_all_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:167: in _migrate_all_forwards
    state = self.apply_migration(
#x1B[1m#x1B[.../new_migrations/monkey/executor.py#x1B[0m:154: in apply_migration
    return super().apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:255: in apply_migration
    state = migration.apply(state, schema_editor)
#x1B[1m#x1B[.../sentry/new_migrations/migrations.py#x1B[0m:28: in apply
    return super().apply(project_state, schema_editor, collect_sql)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/migration.py#x1B[0m:132: in apply
    operation.database_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../migrations/operations/fields.py#x1B[0m:174: in database_forwards
    schema_editor.remove_field(
#x1B[1m#x1B[.../db/postgres/schema.py#x1B[0m:110: in remove_field
    raise UnsafeOperationException(
#x1B[1m#x1B[31mE   django_zero_downtime_migrations.backends.postgres.schema.UnsafeOperationException: Removing the GroupHistory.prev_history field is unsafe.#x1B[0m
#x1B[1m#x1B[31mE   More info here: https://develop.sentry.dev/database-migrations/#deleting-columns#x1B[0m
tests.sentry.monitors.migrations.test_0010_delete_orphaned_detectors.DeleteOrphanedDetectorsTest::test
Stack Traces | 0.002s run time
#x1B[1m#x1B[31m.venv/lib/python3.13........./site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13........./site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13........./site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.../site-packages/pytest_django/fixtures.py#x1B[0m:144: in django_db_setup
    db_cfg = setup_databases(
#x1B[1m#x1B[31m.venv/lib/python3.13.../django/test/utils.py#x1B[0m:204: in setup_databases
    connection.creation.create_test_db(
#x1B[1m#x1B[31m.venv/lib/python3.13.../backends/base/creation.py#x1B[0m:78: in create_test_db
    call_command(
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/__init__.py#x1B[0m:194: in call_command
    return command.execute(*args, **defaults)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:460: in execute
    output = self.handle(*args, **options)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:107: in wrapper
    res = handle_func(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../management/commands/migrate.py#x1B[0m:353: in handle
    post_migrate_state = executor.migrate(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:135: in migrate
    state = self._migrate_all_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:167: in _migrate_all_forwards
    state = self.apply_migration(
#x1B[1m#x1B[.../new_migrations/monkey/executor.py#x1B[0m:154: in apply_migration
    return super().apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:255: in apply_migration
    state = migration.apply(state, schema_editor)
#x1B[1m#x1B[.../sentry/new_migrations/migrations.py#x1B[0m:28: in apply
    return super().apply(project_state, schema_editor, collect_sql)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/migration.py#x1B[0m:132: in apply
    operation.database_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../migrations/operations/fields.py#x1B[0m:174: in database_forwards
    schema_editor.remove_field(
#x1B[1m#x1B[.../db/postgres/schema.py#x1B[0m:110: in remove_field
    raise UnsafeOperationException(
#x1B[1m#x1B[31mE   django_zero_downtime_migrations.backends.postgres.schema.UnsafeOperationException: Removing the GroupHistory.prev_history field is unsafe.#x1B[0m
#x1B[1m#x1B[31mE   More info here: https://develop.sentry.dev/database-migrations/#deleting-columns#x1B[0m
tests.sentry.workflow_engine.migrations.test_0069_rename_error_detectors.RenameErrorDetectorsTest::test
Stack Traces | 0.002s run time
#x1B[1m#x1B[31m.venv/lib/python3.13............/site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13............/site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13............/site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13............/site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.../site-packages/pytest_django/fixtures.py#x1B[0m:144: in django_db_setup
    db_cfg = setup_databases(
#x1B[1m#x1B[31m.venv/lib/python3.13.../django/test/utils.py#x1B[0m:204: in setup_databases
    connection.creation.create_test_db(
#x1B[1m#x1B[31m.venv/lib/python3.13.../backends/base/creation.py#x1B[0m:78: in create_test_db
    call_command(
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/__init__.py#x1B[0m:194: in call_command
    return command.execute(*args, **defaults)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:460: in execute
    output = self.handle(*args, **options)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:107: in wrapper
    res = handle_func(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../management/commands/migrate.py#x1B[0m:353: in handle
    post_migrate_state = executor.migrate(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:135: in migrate
    state = self._migrate_all_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:167: in _migrate_all_forwards
    state = self.apply_migration(
#x1B[1m#x1B[.../new_migrations/monkey/executor.py#x1B[0m:154: in apply_migration
    return super().apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:255: in apply_migration
    state = migration.apply(state, schema_editor)
#x1B[1m#x1B[.../sentry/new_migrations/migrations.py#x1B[0m:28: in apply
    return super().apply(project_state, schema_editor, collect_sql)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/migration.py#x1B[0m:132: in apply
    operation.database_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../migrations/operations/fields.py#x1B[0m:174: in database_forwards
    schema_editor.remove_field(
#x1B[1m#x1B[.../db/postgres/schema.py#x1B[0m:110: in remove_field
    raise UnsafeOperationException(
#x1B[1m#x1B[31mE   django_zero_downtime_migrations.backends.postgres.schema.UnsafeOperationException: Removing the GroupHistory.prev_history field is unsafe.#x1B[0m
#x1B[1m#x1B[31mE   More info here: https://develop.sentry.dev/database-migrations/#deleting-columns#x1B[0m
tests.sentry.workflow_engine.migrations.test_0084_crons_dedupe_workflows.DedupeCronWorkflowsTest::test_migration
Stack Traces | 0.002s run time
#x1B[1m#x1B[31m.venv/lib/python3.13.............../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.............../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.............../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.............../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.............../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.../site-packages/pytest_django/fixtures.py#x1B[0m:144: in django_db_setup
    db_cfg = setup_databases(
#x1B[1m#x1B[31m.venv/lib/python3.13.../django/test/utils.py#x1B[0m:204: in setup_databases
    connection.creation.create_test_db(
#x1B[1m#x1B[31m.venv/lib/python3.13.../backends/base/creation.py#x1B[0m:78: in create_test_db
    call_command(
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/__init__.py#x1B[0m:194: in call_command
    return command.execute(*args, **defaults)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:460: in execute
    output = self.handle(*args, **options)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:107: in wrapper
    res = handle_func(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../management/commands/migrate.py#x1B[0m:353: in handle
    post_migrate_state = executor.migrate(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:135: in migrate
    state = self._migrate_all_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:167: in _migrate_all_forwards
    state = self.apply_migration(
#x1B[1m#x1B[.../new_migrations/monkey/executor.py#x1B[0m:154: in apply_migration
    return super().apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:255: in apply_migration
    state = migration.apply(state, schema_editor)
#x1B[1m#x1B[.../sentry/new_migrations/migrations.py#x1B[0m:28: in apply
    return super().apply(project_state, schema_editor, collect_sql)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/migration.py#x1B[0m:132: in apply
    operation.database_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../migrations/operations/fields.py#x1B[0m:174: in database_forwards
    schema_editor.remove_field(
#x1B[1m#x1B[.../db/postgres/schema.py#x1B[0m:110: in remove_field
    raise UnsafeOperationException(
#x1B[1m#x1B[31mE   django_zero_downtime_migrations.backends.postgres.schema.UnsafeOperationException: Removing the GroupHistory.prev_history field is unsafe.#x1B[0m
#x1B[1m#x1B[31mE   More info here: https://develop.sentry.dev/database-migrations/#deleting-columns#x1B[0m
tests.sentry.workflow_engine.migrations.test_0085_crons_link_detectors_to_all_workflows.LinkCronDetectorsToAllWorkflowsTest::test_migration
Stack Traces | 0.002s run time
#x1B[1m#x1B[31m.venv/lib/python3.13................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.../site-packages/pytest_django/fixtures.py#x1B[0m:144: in django_db_setup
    db_cfg = setup_databases(
#x1B[1m#x1B[31m.venv/lib/python3.13.../django/test/utils.py#x1B[0m:204: in setup_databases
    connection.creation.create_test_db(
#x1B[1m#x1B[31m.venv/lib/python3.13.../backends/base/creation.py#x1B[0m:78: in create_test_db
    call_command(
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/__init__.py#x1B[0m:194: in call_command
    return command.execute(*args, **defaults)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:460: in execute
    output = self.handle(*args, **options)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:107: in wrapper
    res = handle_func(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../management/commands/migrate.py#x1B[0m:353: in handle
    post_migrate_state = executor.migrate(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:135: in migrate
    state = self._migrate_all_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:167: in _migrate_all_forwards
    state = self.apply_migration(
#x1B[1m#x1B[.../new_migrations/monkey/executor.py#x1B[0m:154: in apply_migration
    return super().apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:255: in apply_migration
    state = migration.apply(state, schema_editor)
#x1B[1m#x1B[.../sentry/new_migrations/migrations.py#x1B[0m:28: in apply
    return super().apply(project_state, schema_editor, collect_sql)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/migration.py#x1B[0m:132: in apply
    operation.database_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../migrations/operations/fields.py#x1B[0m:174: in database_forwards
    schema_editor.remove_field(
#x1B[1m#x1B[.../db/postgres/schema.py#x1B[0m:110: in remove_field
    raise UnsafeOperationException(
#x1B[1m#x1B[31mE   django_zero_downtime_migrations.backends.postgres.schema.UnsafeOperationException: Removing the GroupHistory.prev_history field is unsafe.#x1B[0m
#x1B[1m#x1B[31mE   More info here: https://develop.sentry.dev/database-migrations/#deleting-columns#x1B[0m
tests.sentry.workflow_engine.migrations.test_0086_fix_cron_to_cron_workflow_links.FixCronToCronWorkflowLinksTest::test_migration
Stack Traces | 0.002s run time
#x1B[1m#x1B[31m.venv/lib/python3.13...................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13...................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13...................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13...................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13...................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13...................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13...................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.../site-packages/pytest_django/fixtures.py#x1B[0m:144: in django_db_setup
    db_cfg = setup_databases(
#x1B[1m#x1B[31m.venv/lib/python3.13.../django/test/utils.py#x1B[0m:204: in setup_databases
    connection.creation.create_test_db(
#x1B[1m#x1B[31m.venv/lib/python3.13.../backends/base/creation.py#x1B[0m:78: in create_test_db
    call_command(
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/__init__.py#x1B[0m:194: in call_command
    return command.execute(*args, **defaults)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:460: in execute
    output = self.handle(*args, **options)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:107: in wrapper
    res = handle_func(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../management/commands/migrate.py#x1B[0m:353: in handle
    post_migrate_state = executor.migrate(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:135: in migrate
    state = self._migrate_all_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:167: in _migrate_all_forwards
    state = self.apply_migration(
#x1B[1m#x1B[.../new_migrations/monkey/executor.py#x1B[0m:154: in apply_migration
    return super().apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:255: in apply_migration
    state = migration.apply(state, schema_editor)
#x1B[1m#x1B[.../sentry/new_migrations/migrations.py#x1B[0m:28: in apply
    return super().apply(project_state, schema_editor, collect_sql)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/migration.py#x1B[0m:132: in apply
    operation.database_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../migrations/operations/fields.py#x1B[0m:174: in database_forwards
    schema_editor.remove_field(
#x1B[1m#x1B[.../db/postgres/schema.py#x1B[0m:110: in remove_field
    raise UnsafeOperationException(
#x1B[1m#x1B[31mE   django_zero_downtime_migrations.backends.postgres.schema.UnsafeOperationException: Removing the GroupHistory.prev_history field is unsafe.#x1B[0m
#x1B[1m#x1B[31mE   More info here: https://develop.sentry.dev/database-migrations/#deleting-columns#x1B[0m
tests.sentry.workflow_engine.migrations.test_0087_relink_crons_to_compatible_issue_workflows.RelinkCronsToCompatibleIssueWorkflowsTest::test_migration
Stack Traces | 0.002s run time
#x1B[1m#x1B[31m.venv/lib/python3.13......................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13......................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13......................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13......................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13......................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13......................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13......................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13......................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.../site-packages/pytest_django/fixtures.py#x1B[0m:144: in django_db_setup
    db_cfg = setup_databases(
#x1B[1m#x1B[31m.venv/lib/python3.13.../django/test/utils.py#x1B[0m:204: in setup_databases
    connection.creation.create_test_db(
#x1B[1m#x1B[31m.venv/lib/python3.13.../backends/base/creation.py#x1B[0m:78: in create_test_db
    call_command(
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/__init__.py#x1B[0m:194: in call_command
    return command.execute(*args, **defaults)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:460: in execute
    output = self.handle(*args, **options)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:107: in wrapper
    res = handle_func(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../management/commands/migrate.py#x1B[0m:353: in handle
    post_migrate_state = executor.migrate(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:135: in migrate
    state = self._migrate_all_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:167: in _migrate_all_forwards
    state = self.apply_migration(
#x1B[1m#x1B[.../new_migrations/monkey/executor.py#x1B[0m:154: in apply_migration
    return super().apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:255: in apply_migration
    state = migration.apply(state, schema_editor)
#x1B[1m#x1B[.../sentry/new_migrations/migrations.py#x1B[0m:28: in apply
    return super().apply(project_state, schema_editor, collect_sql)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/migration.py#x1B[0m:132: in apply
    operation.database_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../migrations/operations/fields.py#x1B[0m:174: in database_forwards
    schema_editor.remove_field(
#x1B[1m#x1B[.../db/postgres/schema.py#x1B[0m:110: in remove_field
    raise UnsafeOperationException(
#x1B[1m#x1B[31mE   django_zero_downtime_migrations.backends.postgres.schema.UnsafeOperationException: Removing the GroupHistory.prev_history field is unsafe.#x1B[0m
#x1B[1m#x1B[31mE   More info here: https://develop.sentry.dev/database-migrations/#deleting-columns#x1B[0m
tests.sentry.workflow_engine.migrations.test_0088_remove_monitor_slug_conditions.RemoveMonitorSlugConditionsTest::test_migration
Stack Traces | 0.002s run time
#x1B[1m#x1B[31m.venv/lib/python3.13.........................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.........................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.........................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.........................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.........................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.........................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.........................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.........................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.........................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.../site-packages/pytest_django/fixtures.py#x1B[0m:144: in django_db_setup
    db_cfg = setup_databases(
#x1B[1m#x1B[31m.venv/lib/python3.13.../django/test/utils.py#x1B[0m:204: in setup_databases
    connection.creation.create_test_db(
#x1B[1m#x1B[31m.venv/lib/python3.13.../backends/base/creation.py#x1B[0m:78: in create_test_db
    call_command(
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/__init__.py#x1B[0m:194: in call_command
    return command.execute(*args, **defaults)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:460: in execute
    output = self.handle(*args, **options)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:107: in wrapper
    res = handle_func(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../management/commands/migrate.py#x1B[0m:353: in handle
    post_migrate_state = executor.migrate(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:135: in migrate
    state = self._migrate_all_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:167: in _migrate_all_forwards
    state = self.apply_migration(
#x1B[1m#x1B[.../new_migrations/monkey/executor.py#x1B[0m:154: in apply_migration
    return super().apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:255: in apply_migration
    state = migration.apply(state, schema_editor)
#x1B[1m#x1B[.../sentry/new_migrations/migrations.py#x1B[0m:28: in apply
    return super().apply(project_state, schema_editor, collect_sql)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/migration.py#x1B[0m:132: in apply
    operation.database_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../migrations/operations/fields.py#x1B[0m:174: in database_forwards
    schema_editor.remove_field(
#x1B[1m#x1B[.../db/postgres/schema.py#x1B[0m:110: in remove_field
    raise UnsafeOperationException(
#x1B[1m#x1B[31mE   django_zero_downtime_migrations.backends.postgres.schema.UnsafeOperationException: Removing the GroupHistory.prev_history field is unsafe.#x1B[0m
#x1B[1m#x1B[31mE   More info here: https://develop.sentry.dev/database-migrations/#deleting-columns#x1B[0m
tests.sentry.workflow_engine.migrations.test_0089_update_cron_workflow_names.TestUpdateCronWorkflowNames::test_all_workflow_name_scenarios
Stack Traces | 0.002s run time
#x1B[1m#x1B[31m.venv/lib/python3.13............................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13............................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13............................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13............................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13............................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13............................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13............................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13............................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13............................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13............................../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.../site-packages/pytest_django/fixtures.py#x1B[0m:144: in django_db_setup
    db_cfg = setup_databases(
#x1B[1m#x1B[31m.venv/lib/python3.13.../django/test/utils.py#x1B[0m:204: in setup_databases
    connection.creation.create_test_db(
#x1B[1m#x1B[31m.venv/lib/python3.13.../backends/base/creation.py#x1B[0m:78: in create_test_db
    call_command(
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/__init__.py#x1B[0m:194: in call_command
    return command.execute(*args, **defaults)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:460: in execute
    output = self.handle(*args, **options)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:107: in wrapper
    res = handle_func(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../management/commands/migrate.py#x1B[0m:353: in handle
    post_migrate_state = executor.migrate(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:135: in migrate
    state = self._migrate_all_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:167: in _migrate_all_forwards
    state = self.apply_migration(
#x1B[1m#x1B[.../new_migrations/monkey/executor.py#x1B[0m:154: in apply_migration
    return super().apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:255: in apply_migration
    state = migration.apply(state, schema_editor)
#x1B[1m#x1B[.../sentry/new_migrations/migrations.py#x1B[0m:28: in apply
    return super().apply(project_state, schema_editor, collect_sql)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/migration.py#x1B[0m:132: in apply
    operation.database_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../migrations/operations/fields.py#x1B[0m:174: in database_forwards
    schema_editor.remove_field(
#x1B[1m#x1B[.../db/postgres/schema.py#x1B[0m:110: in remove_field
    raise UnsafeOperationException(
#x1B[1m#x1B[31mE   django_zero_downtime_migrations.backends.postgres.schema.UnsafeOperationException: Removing the GroupHistory.prev_history field is unsafe.#x1B[0m
#x1B[1m#x1B[31mE   More info here: https://develop.sentry.dev/database-migrations/#deleting-columns#x1B[0m
tests.sentry.workflow_engine.migrations.test_0091_fix_email_notification_names.TestFixEmailNotificationNames::test_email_notification_names_fixed
Stack Traces | 0.002s run time
#x1B[1m#x1B[31m.venv/lib/python3.13................................./site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13................................./site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13................................./site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13................................./site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13................................./site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13................................./site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13................................./site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13................................./site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13................................./site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13................................./site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13................................./site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.../site-packages/pytest_django/fixtures.py#x1B[0m:144: in django_db_setup
    db_cfg = setup_databases(
#x1B[1m#x1B[31m.venv/lib/python3.13.../django/test/utils.py#x1B[0m:204: in setup_databases
    connection.creation.create_test_db(
#x1B[1m#x1B[31m.venv/lib/python3.13.../backends/base/creation.py#x1B[0m:78: in create_test_db
    call_command(
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/__init__.py#x1B[0m:194: in call_command
    return command.execute(*args, **defaults)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:460: in execute
    output = self.handle(*args, **options)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:107: in wrapper
    res = handle_func(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../management/commands/migrate.py#x1B[0m:353: in handle
    post_migrate_state = executor.migrate(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:135: in migrate
    state = self._migrate_all_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:167: in _migrate_all_forwards
    state = self.apply_migration(
#x1B[1m#x1B[.../new_migrations/monkey/executor.py#x1B[0m:154: in apply_migration
    return super().apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:255: in apply_migration
    state = migration.apply(state, schema_editor)
#x1B[1m#x1B[.../sentry/new_migrations/migrations.py#x1B[0m:28: in apply
    return super().apply(project_state, schema_editor, collect_sql)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/migration.py#x1B[0m:132: in apply
    operation.database_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../migrations/operations/fields.py#x1B[0m:174: in database_forwards
    schema_editor.remove_field(
#x1B[1m#x1B[.../db/postgres/schema.py#x1B[0m:110: in remove_field
    raise UnsafeOperationException(
#x1B[1m#x1B[31mE   django_zero_downtime_migrations.backends.postgres.schema.UnsafeOperationException: Removing the GroupHistory.prev_history field is unsafe.#x1B[0m
#x1B[1m#x1B[31mE   More info here: https://develop.sentry.dev/database-migrations/#deleting-columns#x1B[0m
tests.sentry.monitors.migrations.test_0008_fix_processing_error_keys.FixProcessingErrorKeysTest::test
Stack Traces | 55.6s run time
#x1B[1m#x1B[31m.venv/lib/python3.13.../site-packages/pytest_django/plugin.py#x1B[0m:565: in _django_setup_unittest
    request.getfixturevalue("django_db_setup")
#x1B[1m#x1B[31m.venv/lib/python3.13.../site-packages/pytest_django/fixtures.py#x1B[0m:144: in django_db_setup
    db_cfg = setup_databases(
#x1B[1m#x1B[31m.venv/lib/python3.13.../django/test/utils.py#x1B[0m:204: in setup_databases
    connection.creation.create_test_db(
#x1B[1m#x1B[31m.venv/lib/python3.13.../backends/base/creation.py#x1B[0m:78: in create_test_db
    call_command(
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/__init__.py#x1B[0m:194: in call_command
    return command.execute(*args, **defaults)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:460: in execute
    output = self.handle(*args, **options)
#x1B[1m#x1B[31m.venv/lib/python3.13.../core/management/base.py#x1B[0m:107: in wrapper
    res = handle_func(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../management/commands/migrate.py#x1B[0m:353: in handle
    post_migrate_state = executor.migrate(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:135: in migrate
    state = self._migrate_all_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:167: in _migrate_all_forwards
    state = self.apply_migration(
#x1B[1m#x1B[.../new_migrations/monkey/executor.py#x1B[0m:154: in apply_migration
    return super().apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/executor.py#x1B[0m:255: in apply_migration
    state = migration.apply(state, schema_editor)
#x1B[1m#x1B[.../sentry/new_migrations/migrations.py#x1B[0m:28: in apply
    return super().apply(project_state, schema_editor, collect_sql)
#x1B[1m#x1B[31m.venv/lib/python3.13.../db/migrations/migration.py#x1B[0m:132: in apply
    operation.database_forwards(
#x1B[1m#x1B[31m.venv/lib/python3.13.../migrations/operations/fields.py#x1B[0m:174: in database_forwards
    schema_editor.remove_field(
#x1B[1m#x1B[.../db/postgres/schema.py#x1B[0m:110: in remove_field
    raise UnsafeOperationException(
#x1B[1m#x1B[31mE   django_zero_downtime_migrations.backends.postgres.schema.UnsafeOperationException: Removing the GroupHistory.prev_history field is unsafe.#x1B[0m
#x1B[1m#x1B[31mE   More info here: https://develop.sentry.dev/database-migrations/#deleting-columns#x1B[0m

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@armenzg
Copy link
Member Author

armenzg commented Oct 31, 2025

Alright it seems I need to follow this process first:
https://develop.sentry.dev/backend/application-domains/database-migrations/#deleting-columns

@armenzg armenzg closed this Oct 31, 2025
@armenzg armenzg reopened this Oct 31, 2025
@armenzg armenzg closed this Oct 31, 2025
# 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Bug

The migration to remove the prev_history column is marked is_post_deployment = False. This means the column will be dropped during deployment, risking database errors if older application instances try to access the field. This doesn't align with Sentry's safe column deletion process.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants