-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
ref: serialize release and userReport #10921
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
Conversation
d1b53cc
to
3333f17
Compare
@@ -217,6 +240,9 @@ def serialize(self, obj, attrs, user): | |||
'packages': packages_meta, | |||
'tags': tags_meta, | |||
}, | |||
'release': self._get_release_info(user, obj), | |||
'userReport': self._get_user_report(user, obj), |
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.
i think since this serializer is used for endpoints that return more than a single event (for example ProjectEventsEndpoint
) you may want to do these as bulk queries in get_attrs
to avoid making a query for each item. So for example, you could do:
def get_attrs(self, item_list, user, is_public=False):
...
user_reports = {ur.event_id: ur and serialize(ur, user) for ur in UserReport.objects.filter(
event_id__in=[item.event_id for item in item_list],
project=event.project,
)}
...
for item in item_list:
...
results[item] = {
user_report: user_reports.get(item.event_id),
...
and then in serialize you could just do 'userReport': attrs['user_report']
And then something similar for release.
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.
@macqueen Do you know if this is ever used to serialize lists of events from different projects? because the expression to query for multiple releases might get a little hairy if it does.
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.
hmm good question/point. i think right now, it's only from one project, but with all the stuff we're doing that could easily change in the near future.
to do the bulk query, i think you'd have to do something like this:
releases = list(
Release.objects.filter(
version__in=[i.get_tag('sentry:release') for i in item_list],
projects__in=[i.project_id for i in item_list]
organization_id=item_list[0].project.organization_id, # we could add an assertion that these are from the same org
)
)
releases_by_version = {
r['version']: r for r in serialize(releases, user)
}
release_projects_lookup = defaultdict(set)
for rp in ReleaseProject.objects.filter(
release_id__in=[r.id for r in releases]
).values('release__version', 'project_id'):
release_projects_lookup[rp['release__version']].add(rp{'project_id'})
for item in item_list:
release = releases_by_version.get(item.get_tag('sentry:release'))
if release is not None and item.project_id not in release_projects_lookup[release['version']:
release = None
which as you said, is pretty gross. the other alternative is just doing something like DetailedEventSerializer
which inherits from EventSerializer
and you could just add this stuff there and use that in the details endpoints so it's only adding queries to those?
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.
I mean, I think it would actually be a little grosser than that even, because version__in=..., projects__in=...
will grab the product of all the versions and all the projects, eg if we are looking for version A from project 1 and version B from project 2, it will also grab version A from project 2 and version B from project 1.
So really it'd have to be something like:
Release.objects.filter(Q(version=..., project=...) | Q(version=..., project=...) | ...)
So yeah I think I may just do the subclass thing instead.
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.
Except... I also don't really want 2 serializer classes for 1 class because that kinda breaks the @register() / serialize()
system
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.
we already have this for a few models (see OrganizationSerializer
and DetailedOrganizationSerializer
) -- there's an optional serializer
argument to serialize
to override the register
system
97b6f9b
to
89b3236
Compare
@macqueen OK I think this is ready now with the serialization done in a separate class. |
No description provided.