when no length is present is also deprecated until 0.5; will issue a
warning when used for CREATE TABLE statements (String with no length
for SQL expression purposes is still fine) [ticket:912]
-
+
+ - generative select.order_by(None) / group_by(None) was not managing to
+ reset order by/group by criterion, fixed [ticket:924]
+
- orm
- suppressing *all* errors in InstanceState.__cleanup() now.
-
+
+ - fixed an attribute history bug whereby assigning a new collection
+ to a collection-based attribute which already had pending changes
+ would generate incorrect history [ticket:922]
+
+ - fixed delete-orphan cascade bug whereby setting the same
+ object twice to a scalar attribute could log it as an orphan
+ [ticket:925]
+
- Fixed cascades on a += assignment to a list-based relation.
- synonyms can now be created against props that don't exist yet,
def set_committed_value(self, state, value):
"""set an attribute value on the given instance and 'commit' it."""
- if state.committed_state is not None:
- state.commit_attr(self, value)
+ state.commit_attr(self, value)
# remove per-instance callable, if any
state.callables.pop(self.key, None)
state.dict[self.key] = value
if self.trackparent:
if value is not None:
self.sethasparent(value._state, True)
- if previous is not None:
+ if previous is not value and previous is not None:
self.sethasparent(previous._state, False)
instance = state.obj()
if old is value:
return
- state.committed_state[self.key] = self.copy(old)
+ if self.key not in state.committed_state:
+ state.committed_state[self.key] = self.copy(old)
old_collection = self.get_collection(state, old)
form of this method instead to prevent this issue.
"""
- if clauses == [None]:
+ if len(clauses) == 1 and clauses[0] is None:
self._order_by_clause = ClauseList()
else:
if getattr(self, '_order_by_clause', None):
form of this method instead to prevent this issue.
"""
- if clauses == [None]:
+ if len(clauses) == 1 and clauses[0] is None:
self._group_by_clause = ClauseList()
else:
if getattr(self, '_group_by_clause', None):
s = select([t]).limit(10).offset(20).order_by(t.c.col2)
self.assert_compile(s, "SELECT col1, col2 FROM (SELECT sometable.col1 AS col1, "
- "sometable.col2 AS col2, ROW_NUMBER() OVER (ORDER BY sometable.col2) AS ora_rn FROM sometable ORDER BY sometable.col2) WHERE ora_rn>20 AND ora_rn<=30")
+ "sometable.col2 AS col2, ROW_NUMBER() OVER (ORDER BY sometable.col2) AS ora_rn FROM sometable) WHERE ora_rn>20 AND ora_rn<=30")
def test_outer_join(self):
table1 = table('mytable',
b2.element = None
assert not attributes.has_parent(Bar, f2, 'element')
+
+ # test that double assignment doesn't accidentally reset the 'parent' flag.
+ b3 = Bar()
+ f4 = Foo()
+ b3.element = f4
+ assert attributes.has_parent(Bar, f4, 'element')
+ b3.element = f4
+ assert attributes.has_parent(Bar, f4, 'element')
def test_mutablescalars(self):
"""test detection of changes on mutable scalar items"""
c.students = [s1, s2, s3]
self.assert_(s2.courses == [c])
self.assert_(s1.courses == [c])
- print "--------------------------------"
- print s1
- print s1.courses
- print c
- print c.students
s1.courses.remove(c)
self.assert_(c.students == [s2,s3])
f._state.commit(['someattr'])
self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [there], []))
+
+ f.someattr = [hi]
+ self.assertEquals(attributes.get_history(f._state, 'someattr'), ([hi], [], [there]))
+
+ f.someattr = [old, new]
+ self.assertEquals(attributes.get_history(f._state, 'someattr'), ([old, new], [], [there]))
# case 2. object with direct settings (similar to a load operation)
f = Foo()
f._state.commit(['someattr'])
self.assertEquals(tuple([set(x) for x in attributes.get_history(f._state, 'someattr')]), (set([]), set([hi, there]), set([])))
-
-
def test_object_collections_mutate(self):
class Foo(fixtures.Base):
pass
collection = attributes.init_collection(f, 'someattr')
collection.append_without_event(new)
f._state.commit_all()
- print f._state.dict
self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [new], []))
f.id = 1
f.someattr.remove(new)
self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [], [new]))
+ # case 3. mixing appends with sets
+ f = Foo()
+ f.someattr.append(hi)
+ self.assertEquals(attributes.get_history(f._state, 'someattr'), ([hi], [], []))
+ f.someattr.append(there)
+ self.assertEquals(attributes.get_history(f._state, 'someattr'), ([hi, there], [], []))
+ f.someattr = [there]
+ self.assertEquals(attributes.get_history(f._state, 'someattr'), ([there], [], []))
+
def test_collections_via_backref(self):
class Foo(fixtures.Base):
pass
assert p not in ctx.current
assert e not in ctx.current
+ def testorphan3(self):
+ """test that double assignment doesn't accidentally reset the 'parent' flag."""
+
+ jack = ctx.current.query(User).get_by(user_name='jack')
+ newpref = Pref("newpref")
+ jack.pref = newpref
+ jack.pref = newpref
+ ctx.current.flush()
+
class M2MCascadeTest(AssertMixin):
table2.select(order_by = [table2.c.otherid, table2.c.othername.desc()]),
"SELECT myothertable.otherid, myothertable.othername FROM myothertable ORDER BY myothertable.otherid, myothertable.othername DESC"
)
+
+ # generative order_by
+ self.assert_compile(
+ table2.select().order_by(table2.c.otherid).order_by(table2.c.othername.desc()),
+ "SELECT myothertable.otherid, myothertable.othername FROM myothertable ORDER BY myothertable.otherid, myothertable.othername DESC"
+ )
+
+ self.assert_compile(
+ table2.select().order_by(table2.c.otherid).order_by(table2.c.othername.desc()).order_by(None),
+ "SELECT myothertable.otherid, myothertable.othername FROM myothertable"
+ )
def testgroupby(self):
self.assert_compile(
"SELECT myothertable.othername, count(myothertable.otherid) AS count_1 FROM myothertable GROUP BY myothertable.othername"
)
+ # generative group by
+ self.assert_compile(
+ select([table2.c.othername, func.count(table2.c.otherid)]).group_by(table2.c.othername),
+ "SELECT myothertable.othername, count(myothertable.otherid) AS count_1 FROM myothertable GROUP BY myothertable.othername"
+ )
+
+ self.assert_compile(
+ select([table2.c.othername, func.count(table2.c.otherid)]).group_by(table2.c.othername).group_by(None),
+ "SELECT myothertable.othername, count(myothertable.otherid) AS count_1 FROM myothertable"
+ )
+
def testgroupby_and_orderby(self):
self.assert_compile(