Merge lp:~allenap/storm/get-set-expr-columns into lp:storm

Proposed by Gavin Panella
Status: Work in progress
Proposed branch: lp:~allenap/storm/get-set-expr-columns
Merge into: lp:storm
Prerequisite: lp:~allenap/storm/value-columns-by-name
Diff against target: 75 lines (+35/-1)
3 files modified
storm/expr.py (+14/-0)
tests/expr.py (+10/-0)
tests/store/base.py (+11/-1)
To merge this branch: bzr merge lp:~allenap/storm/get-set-expr-columns
Reviewer Review Type Date Requested Status
James Henstridge Needs Fixing
Review via email: mp+23492@code.launchpad.net

Commit message

ResultSet.values() can now return values from set expressions.

Description of the change

Enables ResultSet.values() to operate on set expressions. It does this with a pass-through property, SetExpr.columns. An alternative implementation could be to deal specially with SetExprs in values() itself.

To post a comment you must log in.
Revision history for this message
James Henstridge (jamesh) wrote :

In most cases, I've used the replace_columns() helper in the store code where I need to fiddle with the column list for a query.

It'd probably be better to do the same in ResultSet.values(). The current code looks like it could leak changes outside of the method call, which could be problematic.

Secondly, I don't believe this patch will result in correct behaviour from ResultSet.values() for set expressions. Consider a table Foo containing the following data:

 id | name
 ---+------
 10 | value
 20 | value

And then do the following:

 result = store.find(Foo, id=10).union(store.find(Foo, id=20))
 print list(result.values(Foo.name))

This will print ['value'] when it should print ['value', 'value']. The result set clearly has two rows, but if we rewrite the column lists to Foo.name then the union will only give us one row.

review: Needs Fixing

Unmerged revisions

358. By Gavin Panella

Tests to show ResultSet.values() working on a set expression.

357. By Gavin Panella

Create a pass-through columns property on SetExpr.

356. By Gavin Panella

ResultSet.values() can now accept column names as well as columns themselves.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'storm/expr.py'
--- storm/expr.py 2009-11-02 11:11:20 +0000
+++ storm/expr.py 2010-04-22 15:57:27 +0000
@@ -1136,6 +1136,20 @@
1136 first.offset is Undef):1136 first.offset is Undef):
1137 self.exprs = first.exprs + self.exprs[1:]1137 self.exprs = first.exprs + self.exprs[1:]
11381138
1139 def _get_columns(self):
1140 if len(self.exprs) > 0:
1141 # The find specs of all sub-expressions should be
1142 # compatible, so simply return the first.
1143 return self.exprs[0].columns
1144 else:
1145 return []
1146
1147 def _set_columns(self, columns):
1148 for expr in self.exprs:
1149 expr.columns = columns
1150
1151 columns = property(_get_columns, _set_columns)
1152
11391153
1140@compile.when(SetExpr)1154@compile.when(SetExpr)
1141def compile_set_expr(compile, expr, state):1155def compile_set_expr(compile, expr, state):
11421156
=== modified file 'tests/expr.py'
--- tests/expr.py 2009-11-02 11:11:20 +0000
+++ tests/expr.py 2010-04-22 15:57:27 +0000
@@ -294,6 +294,16 @@
294 self.assertEquals(expr.expr, objects[0])294 self.assertEquals(expr.expr, objects[0])
295 self.assertEquals(expr.name, objects[1])295 self.assertEquals(expr.name, objects[1])
296296
297 def test_set_expr_columns(self):
298 select1 = Select((elem1, elem2))
299 select2 = Select((elem2, elem1))
300 expr = SetExpr(select1, select2)
301 self.assertEquals((elem1, elem2), expr.columns)
302 expr.columns = []
303 self.assertEquals([], expr.columns)
304 self.assertEquals([], select1.columns)
305 self.assertEquals([], select2.columns)
306
297 def test_union(self):307 def test_union(self):
298 expr = Union(elem1, elem2, elem3)308 expr = Union(elem1, elem2, elem3)
299 self.assertEquals(expr.exprs, (elem1, elem2, elem3))309 self.assertEquals(expr.exprs, (elem1, elem2, elem3))
300310
=== modified file 'tests/store/base.py'
--- tests/store/base.py 2010-04-22 15:57:27 +0000
+++ tests/store/base.py 2010-04-22 15:57:27 +0000
@@ -31,7 +31,7 @@
31from storm.variables import PickleVariable31from storm.variables import PickleVariable
32from storm.expr import (32from storm.expr import (
33 Alias, And, Asc, Avg, Count, Desc, Eq, LeftJoin, Lower, Or, SQL, Select,33 Alias, And, Asc, Avg, Count, Desc, Eq, LeftJoin, Lower, Or, SQL, Select,
34 Sum)34 Sum, Union)
35from storm.variables import Variable, UnicodeVariable, IntVariable35from storm.variables import Variable, UnicodeVariable, IntVariable
36from storm.info import get_obj_info, ClassAlias36from storm.info import get_obj_info, ClassAlias
37from storm.exceptions import *37from storm.exceptions import *
@@ -1047,6 +1047,16 @@
1047 values = self.store.find(Foo).order_by(Foo.id)[1:2].values(Foo.id)1047 values = self.store.find(Foo).order_by(Foo.id)[1:2].values(Foo.id)
1048 self.assertEquals(list(values), [20])1048 self.assertEquals(list(values), [20])
10491049
1050 def test_find_set_expr_values(self):
1051 result = self.store.find(Foo).union(self.store.find(Foo), all=True)
1052 values = result.values(Foo.id)
1053 self.assertEquals(sorted(values), [10, 10, 20, 20, 30, 30])
1054
1055 def test_find_set_expr_values_by_column_name(self):
1056 result = self.store.find(Foo).union(self.store.find(Foo), all=True)
1057 values = result.values('id')
1058 self.assertEquals(sorted(values), [10, 10, 20, 20, 30, 30])
1059
1050 def test_find_remove(self):1060 def test_find_remove(self):
1051 self.store.find(Foo, Foo.id == 20).remove()1061 self.store.find(Foo, Foo.id == 20).remove()
1052 self.assertEquals(self.get_items(), [1062 self.assertEquals(self.get_items(), [

Subscribers

People subscribed via source and target branches

to status/vote changes: