Sorting of Build IDs in project builds gets messed up if you have lots of builds

Bug #1464385 reported by Caio Begotti
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Capomastro
Triaged
Low
Unassigned

Bug Description

See the screenshot attached and you'll notice I had lots of project builds within a day, so the sorting of Build IDs at the bottom of the UI gets messed up because it's the sorting is a simple one, ignoring multiple digits after the period.

That means more than 10 project builds in the same day might trigger this sorting problem, and that could happen very often if people have scheduled builds instead of manual ones.

Revision history for this message
Caio Begotti (caio1982) wrote :
Revision history for this message
Daniel Manrique (roadmr) wrote :

It's similar to the problem system-image-server had with more than 9 builds in a single day. It may have been easier for them to sort since it's Python code and they could have written a custom sort method.

Apparently the projectbuilds context object is created in projects/views.py, in ProjectBuildListView:

    def get_queryset(self):
        return ProjectBuild.objects.filter(
            project=self._get_project_from_url())

I'm not sure any order_by parameter would give us the order we want. This http://stackoverflow.com/questions/883575/custom-ordering-in-django suggests simply using Python ordering for smallish data sets:

qs = ProjectBuild.objects.filter(
            project=self._get_project_from_url())

return sorted(qs, key=lambda x: [int(y) for y in x.split('.')])

This orders lists of integers which will behave as we want, with the downside that the elements of the build id *need* to be convertible to int. Example:

>>> sorted(('2010.1','2010.2','2010.10','2010.80'))
['2010.1', '2010.10', '2010.2', '2010.80'] # Bad ordering
>>> sorted(('2010.1','2010.2','2010.10','2010.80'), key=lambda x: [int(y) for y in x.split('.')])
['2010.1', '2010.2', '2010.10', '2010.80'] # This is good

However, as seen in that stackoverflow answer, this will not work on large sets of builds. The suggested solution, which I'd tend to agree with, is introducing an "order" column to use with order_by() directly in the query set. We could have a data migration which would apply the "split at the dots" for the build ID to populate this column, and then simply incrementally add to it.

Changed in capomastro:
status: New → Triaged
milestone: none → 2015-07
Revision history for this message
Daniel Manrique (roadmr) wrote :

Eh doh, if the table has a primary key of ID, that's already consecutive, right? So how about

ProjectBuild.objects.filter(
            project=self._get_project_from_url()).order_by('pk')

This works. Without order_by('pk') I get this in staging:

[u'20150528.0', u'20150527.5', u'20150527.4', u'20150527.3', u'20150527.2', u'20150527.1', u'20150527.0']

With pk I get:

[u'20150527.0', u'20150527.1', u'20150527.2', u'20150527.3', u'20150527.4', u'20150527.5', u'20150528.0']

This is a tiny, tiny fix.

tags: added: low-hanging-fruit
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.