From 23d1f39ca7112347e6dcbb84577daf363fb04d32 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Fri, 18 Jun 2010 15:11:32 -0400 Subject: [PATCH] add a test for the actual feature, that multiple post updates are batched --- lib/sqlalchemy/orm/unitofwork.py | 4 +- lib/sqlalchemy/test/assertsql.py | 3 +- test/orm/test_cycles.py | 110 +++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 3 deletions(-) diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py index 529a94d5dd..7dc5d69b9f 100644 --- a/lib/sqlalchemy/orm/unitofwork.py +++ b/lib/sqlalchemy/orm/unitofwork.py @@ -274,10 +274,10 @@ class UOWTransaction(object): def execute(self): postsort_actions = self._generate_actions() - sort = topological.sort(self.dependencies, postsort_actions) + #sort = topological.sort(self.dependencies, postsort_actions) #print "--------------" #print self.dependencies - print list(sort) + #print list(sort) #print "COUNT OF POSTSORT ACTIONS", len(postsort_actions) # execute diff --git a/lib/sqlalchemy/test/assertsql.py b/lib/sqlalchemy/test/assertsql.py index d363d33132..a044f9d02f 100644 --- a/lib/sqlalchemy/test/assertsql.py +++ b/lib/sqlalchemy/test/assertsql.py @@ -138,7 +138,7 @@ class CompiledSQL(SQLMatchRule): if not context: return - _received_parameters = context.compiled_parameters + _received_parameters = list(context.compiled_parameters) # recompile from the context, using the default dialect compiled = context.compiled.statement.\ @@ -178,6 +178,7 @@ class CompiledSQL(SQLMatchRule): self._errmsg = "Testing for compiled statement %r partial params %r, " \ "received %r with params %r" % \ (self.statement, all_params, _received_statement, all_received) + #print self._errmsg class CountStatements(AssertRule): diff --git a/test/orm/test_cycles.py b/test/orm/test_cycles.py index e86b2c8ae0..8848831217 100644 --- a/test/orm/test_cycles.py +++ b/test/orm/test_cycles.py @@ -1018,3 +1018,113 @@ class SelfReferentialPostUpdateTest3(_base.MappedTest): p1.child = None session.flush() + p2.child = None + session.flush() + +class PostUpdateBatchingTest(_base.MappedTest): + """test that lots of post update cols batch together into a single UPDATE.""" + + @classmethod + def define_tables(cls, metadata): + Table('parent', metadata, + Column('id', Integer, primary_key=True, + test_needs_autoincrement=True), + Column('name', String(50), nullable=False), + Column('c1_id', Integer, + ForeignKey('child1.id', use_alter=True, name='c1'), nullable=True), + Column('c2_id', Integer, + ForeignKey('child2.id', use_alter=True, name='c2'), nullable=True), + Column('c3_id', Integer, + ForeignKey('child3.id', use_alter=True, name='c3'), nullable=True) + ) + + Table('child1', metadata, + Column('id', Integer, primary_key=True, + test_needs_autoincrement=True), + Column('name', String(50), nullable=False), + Column('parent_id', Integer, + ForeignKey('parent.id'), nullable=False)) + + Table('child2', metadata, + Column('id', Integer, primary_key=True, + test_needs_autoincrement=True), + Column('name', String(50), nullable=False), + Column('parent_id', Integer, + ForeignKey('parent.id'), nullable=False)) + + Table('child3', metadata, + Column('id', Integer, primary_key=True, + test_needs_autoincrement=True), + Column('name', String(50), nullable=False), + Column('parent_id', Integer, + ForeignKey('parent.id'), nullable=False)) + + @classmethod + def setup_classes(cls): + class Parent(_base.BasicEntity): + def __init__(self, name=''): + self.name = name + class Child1(_base.BasicEntity): + def __init__(self, name=''): + self.name = name + class Child2(_base.BasicEntity): + def __init__(self, name=''): + self.name = name + class Child3(_base.BasicEntity): + def __init__(self, name=''): + self.name = name + + @testing.resolve_artifact_names + def test_one(self): + mapper(Parent, parent, properties={ + 'c1s':relationship(Child1, primaryjoin=child1.c.parent_id==parent.c.id), + 'c2s':relationship(Child2, primaryjoin=child2.c.parent_id==parent.c.id), + 'c3s':relationship(Child3, primaryjoin=child3.c.parent_id==parent.c.id), + + 'c1':relationship(Child1, primaryjoin=child1.c.id==parent.c.c1_id, post_update=True), + 'c2':relationship(Child2, primaryjoin=child2.c.id==parent.c.c2_id, post_update=True), + 'c3':relationship(Child3, primaryjoin=child3.c.id==parent.c.c3_id, post_update=True), + }) + mapper(Child1, child1) + mapper(Child2, child2) + mapper(Child3, child3) + + sess = create_session() + + p1 = Parent('p1') + c11, c12, c13 = Child1('c1'), Child1('c2'), Child1('c3') + c21, c22, c23 = Child2('c1'), Child2('c2'), Child2('c3') + c31, c32, c33 = Child3('c1'), Child3('c2'), Child3('c3') + + p1.c1s = [c11, c12, c13] + p1.c2s = [c21, c22, c23] + p1.c3s = [c31, c32, c33] + sess.add(p1) + sess.flush() + + p1.c1 = c12 + p1.c2 = c23 + p1.c3 = c31 + + self.assert_sql_execution( + testing.db, + sess.flush, + CompiledSQL( + "UPDATE parent SET c1_id=:c1_id, c2_id=:c2_id, " + "c3_id=:c3_id WHERE parent.id = :parent_id", + lambda ctx: {'c2_id': c23.id, 'parent_id': p1.id, 'c1_id': c12.id, 'c3_id': c31.id} + ) + ) + + p1.c1 = p1.c2 = p1.c3 = None + + self.assert_sql_execution( + testing.db, + sess.flush, + CompiledSQL( + "UPDATE parent SET c1_id=:c1_id, c2_id=:c2_id, " + "c3_id=:c3_id WHERE parent.id = :parent_id", + lambda ctx: {'c2_id': None, 'parent_id': p1.id, 'c1_id': None, 'c3_id': None} + ) + ) + \ No newline at end of file -- 2.47.2