From beb38b0fd2422c4e0dffd526234116e4db16d6e4 Mon Sep 17 00:00:00 2001 From: mprahl Date: Wed, 15 May 2019 09:47:26 -0400 Subject: [PATCH] Modify ModuleBuild._add_virtual_streams_filter to use a subquery to better support Postgres The old way performed a `DISTINCT (module_builds.id)` on the original query passed in to ModuleBuild._add_virtual_streams_filter, but this caused issues when the original query was ordered by something other than ID on Postgres databases. This new approach uses a subquery to filter that module builds with the desired virtual streams, and then joins this subquery to the original query. --- module_build_service/models.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/module_build_service/models.py b/module_build_service/models.py index 52d11be4..24fca780 100644 --- a/module_build_service/models.py +++ b/module_build_service/models.py @@ -419,11 +419,21 @@ class ModuleBuild(MBSBase): if not virtual_streams: return query - return ( - query.join(VirtualStream, ModuleBuild.virtual_streams) + # Create a subquery that filters down all the module builds that contain the virtual + # streams. Using distinct is necessary since a module build may contain multiple virtual + # streams that are desired. + modules_with_virtual_streams = ( + session.query(ModuleBuild) + .join(VirtualStream, ModuleBuild.virtual_streams) .filter(VirtualStream.name.in_(virtual_streams)) + .order_by(ModuleBuild.id) .distinct(ModuleBuild.id) - ) + ).subquery() + + # Join the original query with the subquery so that only module builds with the desired + # virtual streams remain + return query.join( + modules_with_virtual_streams, ModuleBuild.id == modules_with_virtual_streams.c.id) @staticmethod def get_last_builds_in_stream_version_lte(session, name, stream_version, virtual_streams=None):