-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(aci): Add migration to check group id for exclusion constraint #88484
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅ ✅ All tests successful. No failed tests found. Additional details and impacted files@@ Coverage Diff @@
## master #88484 +/- ##
===========================================
+ Coverage 32.99% 87.76% +54.77%
===========================================
Files 8480 10027 +1547
Lines 474576 567682 +93106
Branches 22311 22246 -65
===========================================
+ Hits 156568 498213 +341645
+ Misses 317588 69050 -248538
+ Partials 420 419 -1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this seems right!
src/sentry/migrations/0855_update_group_open_periods_constraint.py
Outdated
Show resolved
Hide resolved
b56a942
to
dead23f
Compare
dead23f
to
e1885d1
Compare
This PR has a migration; here is the generated SQL for --
-- Remove constraint exclude_open_period_overlap from model groupopenperiod
--
ALTER TABLE "sentry_groupopenperiod" DROP CONSTRAINT "exclude_open_period_overlap";
--
-- Create constraint exclude_open_period_overlap on model groupopenperiod
--
ALTER TABLE "sentry_groupopenperiod" ADD CONSTRAINT "exclude_open_period_overlap" EXCLUDE USING GIST ("group_id" WITH =, (TSTZRANGE("date_started", "date_ended", '[)')) WITH &&); |
This PR has a migration; here is the generated SQL for --
-- Remove constraint exclude_open_period_overlap from model groupopenperiod
--
ALTER TABLE "sentry_groupopenperiod" DROP CONSTRAINT "exclude_open_period_overlap";
--
-- Custom state/database change combination
--
ALTER TABLE "sentry_groupopenperiod"
ADD CONSTRAINT "exclude_open_period_overlap" EXCLUDE USING GIST (
"group_id" gist_int8_ops WITH =,
(TSTZRANGE("date_started", "date_ended", '[)')) WITH &&
); |
migrations.AddConstraint( | ||
model_name="groupopenperiod", | ||
constraint=django.contrib.postgres.constraints.ExclusionConstraint( | ||
expressions=[ | ||
(models.F("group"), "="), | ||
( | ||
sentry.models.groupopenperiod.TsTzRange( | ||
"date_started", | ||
"date_ended", | ||
django.contrib.postgres.fields.ranges.RangeBoundary(), | ||
), | ||
"&&", | ||
), | ||
], | ||
name="exclude_open_period_overlap", | ||
), | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So as far as I can tell, we need to pass opsclasses here to use the bigint col in this constraint. There's no way to do this in Django for now.
So let's use SeparateDatabaseAndState. Put this AddConstraint
in the state, and use add this to the database
SafeRunSQL("""ALTER TABLE "sentry_groupopenperiod"
ADD CONSTRAINT "exclude_open_period_overlap" EXCLUDE USING GIST (
"group_id" gist_int8_ops WITH =,
(TSTZRANGE("date_started", "date_ended", '[)')) WITH &&
);""", use_statement_timeout=False)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, damn... I think I know why it's failing on most tests.
When we generate the database without migrations, it looks at the model definition and produces the sql... so it's still creating the GIST in the wrong way.
Basically, there's not a great way to make this index and have it on the table definition.
What we could do is include the ExclusionConstraint
as a comment where it is now, and explain why we can't actually define it in the code. Then just create it using SafeRunSQL
, and not have any state representing this exclusion constraint.
You can also set remove the checked = False
line since we won't be explicitly checking anymore
This PR has a migration; here is the generated SQL for --
-- Remove constraint exclude_open_period_overlap from model groupopenperiod
--
ALTER TABLE "sentry_groupopenperiod" DROP CONSTRAINT "exclude_open_period_overlap";
--
-- Raw SQL operation
--
ALTER TABLE "sentry_groupopenperiod"
ADD CONSTRAINT "exclude_open_period_overlap" EXCLUDE USING GIST (
"group_id" gist_int8_ops WITH =,
(TSTZRANGE("date_started", "date_ended", '[)')) WITH &&
); |
migrations.AddConstraint( | ||
model_name="groupopenperiod", | ||
constraint=django.contrib.postgres.constraints.ExclusionConstraint( | ||
expressions=[ | ||
(models.F("group"), "="), | ||
( | ||
sentry.models.groupopenperiod.TsTzRange( | ||
"date_started", | ||
"date_ended", | ||
django.contrib.postgres.fields.ranges.RangeBoundary(), | ||
), | ||
"&&", | ||
), | ||
], | ||
name="exclude_open_period_overlap", | ||
), | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove the state operation, django won't be aware of this because it doesn't exist on the model. You can remove the SeparateDatabaseAndState
in general and put the SafeRunSQL
as its own operation
…88484) The existing exclusion constraint looks only for overlapping ranges of (date_started, date_ended). We need to enforce this constraint for each group, so that no distinct group has two open periods that overlap. The table itself is expected to have multiple overlapping ranges since we'll have one row per group.
The previous attempt (#88484) to do this failed because of the order of operations, so we've split this up into two steps: 1. remove the existing constraint #88708 2. add a new updated constraint (this pr) Note that the table is empty. For context, the old exclusion constraint looks only for overlapping ranges of (date_started, date_ended). We need to enforce this constraint for each group, so that no distinct group has two open periods that overlap. The table itself is expected to have multiple overlapping ranges since we'll have one row per group.
…88484) The existing exclusion constraint looks only for overlapping ranges of (date_started, date_ended). We need to enforce this constraint for each group, so that no distinct group has two open periods that overlap. The table itself is expected to have multiple overlapping ranges since we'll have one row per group.
The previous attempt (#88484) to do this failed because of the order of operations, so we've split this up into two steps: 1. remove the existing constraint #88708 2. add a new updated constraint (this pr) Note that the table is empty. For context, the old exclusion constraint looks only for overlapping ranges of (date_started, date_ended). We need to enforce this constraint for each group, so that no distinct group has two open periods that overlap. The table itself is expected to have multiple overlapping ranges since we'll have one row per group.
The existing exclusion constraint looks only for overlapping ranges of (date_started, date_ended). We need to enforce this constraint for each group, so that no distinct group has two open periods that overlap. The table itself is expected to have multiple overlapping ranges since we'll have one row per group.