summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2006-05-29 17:21:41 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2006-05-29 17:21:41 +0000
commit50e5619a48b584872a4ddf8b6003cfce80d0cf1b (patch)
tree574e9f691f40d34278e78f6a1fbe410e59a1bb3d
parent11fab37133fd2ae155179d64079965f307b4d57c (diff)
downloadsqlalchemy-50e5619a48b584872a4ddf8b6003cfce80d0cf1b.tar.gz
more polymorphic adjustments to circular dependency sort
-rw-r--r--doc/build/content/dbengine.txt2
-rw-r--r--lib/sqlalchemy/orm/mapper.py10
-rw-r--r--lib/sqlalchemy/orm/properties.py10
-rw-r--r--lib/sqlalchemy/orm/unitofwork.py20
4 files changed, 25 insertions, 17 deletions
diff --git a/doc/build/content/dbengine.txt b/doc/build/content/dbengine.txt
index 2193ab6b5..715e274fa 100644
--- a/doc/build/content/dbengine.txt
+++ b/doc/build/content/dbengine.txt
@@ -192,7 +192,7 @@ To get at the actual `Connection` object which is used by implicit executions, c
conn1 = db.contextual_connection()
conn2 = db.contextual_connection()
- >>> assert conn1 is conn2
+ >>> assert conn1.connection is conn2.connection
True
When the `plain` strategy is used, the `contextual_connection()` method is synonymous with the `connect()` method; both return a distinct connection from the pool.
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index 07e4f503d..11806ea8f 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -231,7 +231,7 @@ class Mapper(object):
if self.columntoproperty.has_key(column):
continue
if not self.columns.has_key(column.key):
- self.columns[column.key] = column
+ self.columns[column.key] = self.select_table.corresponding_column(column, keys_ok=True, raiseerr=True)
prop = self.props.get(column.key, None)
if prop is None:
@@ -291,7 +291,11 @@ class Mapper(object):
return self.inherits.base_mapper()
else:
return self
-
+
+ def _inherits(self, mapper):
+ """returns True if the given mapper and this mapper are in the same inheritance hierarchy"""
+ return self.base_mapper() is mapper.base_mapper()
+
def add_polymorphic_mapping(self, key, class_or_mapper, entity_name=None):
if isinstance(class_or_mapper, type):
class_or_mapper = class_mapper(class_or_mapper, entity_name=entity_name)
@@ -338,7 +342,7 @@ class Mapper(object):
self.props[key] = prop
if isinstance(prop, ColumnProperty):
- self.columns[key] = prop.columns[0]
+ self.columns[key] = self.select_table.corresponding_column(prop.columns[0], keys_ok=True, raiseerr=True)
for col in prop.columns:
proplist = self.columntoproperty.setdefault(col, [])
proplist.append(prop)
diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py
index 9f8883a31..8c38b897f 100644
--- a/lib/sqlalchemy/orm/properties.py
+++ b/lib/sqlalchemy/orm/properties.py
@@ -150,12 +150,9 @@ class PropertyLoader(mapper.MapperProperty):
private = property(lambda s:s.cascade.delete_orphan)
- def cascade_iterator(self, type, object, recursive=None):
+ def cascade_iterator(self, type, object, recursive):
if not type in self.cascade:
return
- if recursive is None:
- recursive = sets.Set()
-
childlist = sessionlib.global_attributes.get_history(object, self.key, passive=True)
for c in childlist.added_items() + childlist.deleted_items() + childlist.unchanged_items():
@@ -163,7 +160,7 @@ class PropertyLoader(mapper.MapperProperty):
if c not in recursive:
recursive.add(c)
yield c
- for c2 in self.mapper.cascade_iterator(type, c, recursive):
+ for c2 in self.mapper.primary_mapper().cascade_iterator(type, c, recursive):
yield c2
def copy(self):
@@ -247,10 +244,9 @@ class PropertyLoader(mapper.MapperProperty):
def _get_direction(self):
"""determines our 'direction', i.e. do we represent one to many, many to many, etc."""
-
if self.secondaryjoin is not None:
return sync.MANYTOMANY
- elif self.parent.mapped_table is self.target:
+ elif self.parent.mapped_table is self.target or self.parent.select_table is self.target:
if self.foreignkey.primary_key:
return sync.MANYTOONE
else:
diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py
index 1ebf9cd69..3927b949e 100644
--- a/lib/sqlalchemy/orm/unitofwork.py
+++ b/lib/sqlalchemy/orm/unitofwork.py
@@ -761,8 +761,9 @@ class UOWTask(object):
for dep in task.dependencies:
if not dependency_in_cycles(dep):
extradeplist.append(dep)
- l = deps_by_targettask.setdefault(dep.targettask, [])
- l.append(dep)
+ for t in dep.targettask.polymorphic_tasks():
+ l = deps_by_targettask.setdefault(t, [])
+ l.append(dep)
for t in cycles:
for task in t.polymorphic_tasks():
@@ -771,8 +772,10 @@ class UOWTask(object):
object_to_original_task[obj] = task
#print "OBJ", repr(obj), "TASK", repr(task)
+
for dep in deps_by_targettask.get(task, []):
# is this dependency involved in one of the cycles ?
+ #print "DEP iterate", dep.processor.key
if not dependency_in_cycles(dep):
continue
#print "DEP", dep.processor.key
@@ -790,8 +793,9 @@ class UOWTask(object):
for o in childlist:
if o is None or not childtask.contains_object(o, polymorphic=True):
continue
- #print "CHILD", o
+ #print "parent/child", obj, o
whosdep = dep.whose_dependent_on_who(obj, o)
+ #print "WHOSEDEP", dep.processor.key, dep.processor.direction, whosdep
if whosdep is not None:
tuples.append(whosdep)
# create a UOWDependencyProcessor representing this pair of objects.
@@ -820,13 +824,17 @@ class UOWTask(object):
def make_task_tree(node, parenttask):
"""takes a dependency-sorted tree of objects and creates a tree of UOWTasks"""
- #print "MAKETASKTREE", node.item
+ #print "MAKETASKTREE", node.item, parenttask
t = get_object_task(node.item)
for n in node.children:
t2 = make_task_tree(n, t)
-
- can_add_to_parent = t.mapper is parenttask.mapper
+
+ # this flag is attempting to coalesce non-dependent operations into lists, instead of
+ # individual tasks, to produce more of a "batching" effect. great when it works,
+ # but easily breakable...so its at False for now
+ can_add_to_parent = False #parenttask.mapper._inherits(t.mapper)
+
original_task = object_to_original_task[node.item]
#print "ORIG TASK", original_task
if original_task.contains_object(node.item, polymorphic=False):