Repository: wearewhys/magnivore

Issue:
Add ability to specify selected columns
It should be possible to specify the columns to be selected in when retrieving items. This is necessary as it would allow to retrieve aggregated sets e.g. count queries

Discussion:

Patch:
diff --git a/magnivore/Targets.py b/magnivore/Targets.py
index c2aa61c..27ce660 100644
--- a/magnivore/Targets.py
+++ b/magnivore/Targets.py
@@ -66,6 +66,16 @@ class Targets:
             return query.join(model, 'LEFT OUTER', on=expression)
         return query.join(model, on=expression)
 
+    def _apply_pick(self, query, join):
+        model = self.source_models[join['table']]
+        selects = []
+        for column, value in join['picks'].items():
+            if value is True:
+                selects.append(getattr(model, column))
+            elif value == 'sum':
+                selects.append(fn.Sum(getattr(model, column)))
+        return query.select(*selects)
+
     def get(self, joins, limit=None, offset=0):
         """
         Retrieves the targets for the given joins
@@ -76,6 +86,7 @@ class Targets:
         aggregations = []
         conditions = []
         models = []
+        picks = []
         for join in joins:
             models.append(self.source_models[join['table']])
             if 'conditions' in join:
@@ -84,7 +95,14 @@ class Targets:
             if 'aggregation' in join:
                 aggregations.append(join)
 
-        query = models[0].select(*models)
+            if 'picks' in join:
+                picks.append(join)
+
+        query = models[0]
+        if picks == []:
+            query = query.select(*models)
+        for pick in picks:
+            query = self._apply_pick(query, pick)
 
         joins.pop(0)
         for join in joins:


Test patch:
diff --git a/tests/unit/Targets.py b/tests/unit/Targets.py
index a0668e5..159af9c 100644
--- a/tests/unit/Targets.py
+++ b/tests/unit/Targets.py
@@ -193,6 +193,24 @@ def test_get_aggregations_eq(mocker, targets, joins, nodes, nodes_query):
     assert nodes_query.join().group_by().having().execute.call_count == 1
 
 
+def test_get_picks(targets, joins, nodes, nodes_query):
+    joins[0]['picks'] = {
+        'field': True
+    }
+    targets.get(joins)
+    nodes.select.assert_called_with(nodes.field)
+    assert nodes_query.join().execute.call_count == 1
+
+
+def test_get_picks_sum(targets, joins, nodes, nodes_query):
+    joins[0]['picks'] = {
+        'field': 'sum'
+    }
+    targets.get(joins)
+    nodes.select.assert_called_with(fn.Sum(nodes.field))
+    assert nodes_query.join().execute.call_count == 1
+
+
 def test_get_log_query(targets, joins, nodes_query, logger):
     targets.get(joins)
     calls = [call.logger.log('get-targets', nodes_query.join())]