summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2010-04-10 20:13:51 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2010-04-10 20:13:51 -0400
commitcf65d1e42e61e637653367b9fc484e98e8829c7f (patch)
tree7bc111c0f1bb0d528a062a55fbcd1db902624872
parentcf9cac34ac8df5613ef2d24884030df8aa749580 (diff)
downloadsqlalchemy-cf65d1e42e61e637653367b9fc484e98e8829c7f.tar.gz
check_reverse was failing a not well covered m2m case.
-rw-r--r--lib/sqlalchemy/orm/dependency.py5
-rw-r--r--lib/sqlalchemy/orm/unitofwork.py3
-rw-r--r--test/aaa_profiling/test_memusage.py2
-rw-r--r--test/orm/test_manytomany.py56
4 files changed, 62 insertions, 4 deletions
diff --git a/lib/sqlalchemy/orm/dependency.py b/lib/sqlalchemy/orm/dependency.py
index 316c5382d..b84794699 100644
--- a/lib/sqlalchemy/orm/dependency.py
+++ b/lib/sqlalchemy/orm/dependency.py
@@ -278,8 +278,9 @@ class DependencyProcessor(object):
"""
for p in self.prop._reverse_property:
- if not p.viewonly and p._dependency_processor:
- return p.key < self.key
+ if not p.viewonly and p._dependency_processor and \
+ uow.has_dep(p._dependency_processor):
+ return True
else:
return False
diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py
index 2c616943f..756389fa7 100644
--- a/lib/sqlalchemy/orm/unitofwork.py
+++ b/lib/sqlalchemy/orm/unitofwork.py
@@ -156,6 +156,9 @@ class UOWTransaction(object):
else:
return history.as_state()
+ def has_dep(self, processor):
+ return (processor, True) in self.presort_actions
+
def register_preprocessor(self, processor, fromparent):
key = (processor, fromparent)
if key not in self.presort_actions:
diff --git a/test/aaa_profiling/test_memusage.py b/test/aaa_profiling/test_memusage.py
index ba1f67ddf..711b03a02 100644
--- a/test/aaa_profiling/test_memusage.py
+++ b/test/aaa_profiling/test_memusage.py
@@ -301,7 +301,7 @@ class MemUsageTest(EnsureZeroed):
# dont need to clear_mappers()
del B
del A
-
+
metadata.create_all()
try:
go()
diff --git a/test/orm/test_manytomany.py b/test/orm/test_manytomany.py
index 84c60fc28..cac5fda78 100644
--- a/test/orm/test_manytomany.py
+++ b/test/orm/test_manytomany.py
@@ -1,4 +1,4 @@
-from sqlalchemy.test.testing import assert_raises, assert_raises_message
+from sqlalchemy.test.testing import assert_raises, assert_raises_message, eq_
import sqlalchemy as sa
from sqlalchemy.test import testing
from sqlalchemy import Integer, String, ForeignKey
@@ -327,4 +327,58 @@ class M2MTest3(_base.MappedTest):
# TODO: seems like just a test for an ancient exception throw.
# how about some data/inserts/queries/assertions for this one
+class M2MTest4(_base.MappedTest):
+ @classmethod
+ def define_tables(cls, metadata):
+ table1 = Table("table1", metadata,
+ Column('col1', Integer, primary_key=True, test_needs_autoincrement=True),
+ Column('col2', String(30))
+ )
+
+ table2 = Table("table2", metadata,
+ Column('col1', Integer, primary_key=True, test_needs_autoincrement=True),
+ Column('col2', String(30)),
+ )
+
+ table3 = Table('table3', metadata,
+ Column('t1', Integer, ForeignKey('table1.col1')),
+ Column('t2', Integer, ForeignKey('table2.col1')),
+ )
+
+ @testing.resolve_artifact_names
+ def test_delete_parent(self):
+ class A(_base.ComparableEntity):
+ pass
+ class B(_base.ComparableEntity):
+ pass
+
+ mapper(A, table1, properties={
+ 'bs':relationship(B, secondary=table3, backref='as', order_by=table3.c.t1)
+ })
+ mapper(B, table2)
+
+ sess = create_session()
+ a1 = A(col2='a1')
+ a2 = A(col2='a2')
+ b1 = B(col2='b1')
+ b2 = B(col2='b2')
+ a1.bs.append(b1)
+ a2.bs.append(b2)
+ for x in [a1,a2]:
+ sess.add(x)
+ sess.flush()
+ sess.expunge_all()
+
+ alist = sess.query(A).order_by(A.col1).all()
+ eq_(
+ [
+ A(bs=[B(col2='b1')]), A(bs=[B(col2='b2')])
+ ],
+ alist)
+
+ for a in alist:
+ sess.delete(a)
+ sess.flush()
+ eq_(sess.query(table3).count(), 0)
+