Skip to content

Conversation

@mattrobenolt
Copy link
Contributor

I want to get this schema change out of the way now before affecting the rest of the API changes since this will be a tad hairy in production.

evanpurkhiser
evanpurkhiser previously approved these changes Jan 26, 2018
Copy link
Member

@evanpurkhiser evanpurkhiser left a comment

Choose a reason for hiding this comment

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

Looks good. Curious what the deploy process in prod will look like for this.

def assign(self, group, assigned_to, acting_user=None):
from sentry.models import User, Team

if isinstance(assigned_to, User):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tkaemming I want your opinion on this.

I originally wanted to do some abstraction of Actor, but turns out, this Actor also would need to encapsulate the same logic, and in this case GroupAssignee is just this actor abstraction. I also chose to do this with two different columns, user_id and team_id instead of an alternative Django "generic" FK style, where there's a column for model and object_id, this allows us to still use actual ForeignKeys, which being a tad more rigid since it can't FK against anything, which is a good thing here.


# Flag to indicate if this migration is too risky
# to run online and needs to be coordinated for offline
is_dangerous = True
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am 100% doing this by hand since the SQL that South spits out is not great at all.

 > sentry:0386_auto__add_field_groupassignee_team__chg_field_groupassignee_user
   = ALTER TABLE "sentry_groupasignee" ADD COLUMN "team_id" bigint NULL; []
   = ALTER TABLE "sentry_groupasignee" ALTER COLUMN "team_id" TYPE bigint, ALTER COLUMN "team_id" DROP NOT NULL, ALTER COLUMN "team_id" DROP DEFAULT; []
 [...]
   = ALTER TABLE "sentry_groupasignee" DROP CONSTRAINT "user_id_refs_id_f4dcb8d1" []
   = ALTER TABLE "sentry_groupasignee" ALTER COLUMN "user_id" TYPE integer, ALTER COLUMN "user_id" DROP NOT NULL, ALTER COLUMN "user_id" DROP DEFAULT; []
   = ALTER TABLE "sentry_groupasignee" ADD CONSTRAINT "user_id_refs_id_f4dcb8d1" FOREIGN KEY ("user_id") REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED; []
   = ALTER TABLE "sentry_groupasignee" ADD CONSTRAINT "team_id_refs_id_5b32ca44" FOREIGN KEY ("team_id") REFERENCES "sentry_team" ("id") DEFERRABLE INITIALLY DEFERRED; []
   = CREATE INDEX "sentry_groupasignee_team_id" ON "sentry_groupasignee" ("team_id"); []

Copy link
Contributor

Choose a reason for hiding this comment

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

lol

__repr__ = sane_repr('group_id', 'user_id', 'team_id')

def save(self, *args, **kwargs):
assert self.user_id or self.team_id
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm thinking about applying a migration as well to put a real constraint on this to enforce it at the database.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 on making this a defined check constraint; I'd also strongly consider ensuring that only one of the two is set (require of the fields to be set and only allow one of the fields to be set) both here as well as in the check constraint.

I have no idea how we'd hook these check constraints in to to run correctly during tests… add SQL manually to the migration somehow?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ALTER TABLE sentry_groupasignee
ADD CONSTRAINT require_team_or_user_but_not_both
CHECK (
    NOT (team_id IS NOT NULL AND user_id IS NOT NULL) AND
    NOT (team_id IS NULL AND user_id IS NULL)
);

😎

Copy link
Contributor

Choose a reason for hiding this comment

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

:nice:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mattrobenolt mattrobenolt requested a review from a team January 26, 2018 01:50
@ghost
Copy link

ghost commented Jan 26, 2018

2 Warnings
⚠️ You should update CHANGES due to the size of this PR
⚠️ PR includes migrations

Migration Checklist

  • new columns need to be nullable (unless table is new)
  • migration with any new index needs to be done concurrently
  • data migrations should not be done inside a transaction
  • before merging, check to make sure there aren't conflicting migration ids

Generated by 🚫 danger

}).update(**{
assignee_type: assigned_to,
'date_added': now,
})
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this null out the other type field if it's updating the row (e.g. set user to None if you're setting team and vice versa.)

Copy link
Member

Choose a reason for hiding this comment

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

Good call

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in e1bfec9 and added tests.

__repr__ = sane_repr('group_id', 'user_id', 'team_id')

def save(self, *args, **kwargs):
assert self.user_id or self.team_id
Copy link
Contributor

Choose a reason for hiding this comment

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

+1 on making this a defined check constraint; I'd also strongly consider ensuring that only one of the two is set (require of the fields to be set and only allow one of the fields to be set) both here as well as in the check constraint.

I have no idea how we'd hook these check constraints in to to run correctly during tests… add SQL manually to the migration somehow?

Copy link
Contributor

@tkaemming tkaemming left a comment

Choose a reason for hiding this comment

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

LOOKS GOOD

@mattrobenolt
Copy link
Contributor Author

The failure is just selenium being selenium.

@mattrobenolt mattrobenolt merged commit 4b66584 into master Feb 2, 2018
@mattrobenolt mattrobenolt deleted the groupassignee-team branch February 2, 2018 23:58
@github-actions github-actions bot locked and limited conversation to collaborators Dec 22, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants