pass
def delete_obj(self, *args, **kwargs):
pass
- def _primary_mapper(self):
+ def primary_mapper(self):
return self
def base_mapper(self):
return self
\ No newline at end of file
# tables - a collection of underlying Table objects pulled from mapped_table
for table in (local_table, select_table):
- if table is not None and isinstance(local_table, sql.SelectBaseMixin):
+ if table is not None and isinstance(table, sql.SelectBaseMixin):
# some db's, noteably postgres, dont want to select from a select
# without an alias. also if we make our own alias internally, then
# the configured properties on the mapper are not matched against the alias
else:
self.select_table = self.mapped_table
self.unjoined_table = self.local_table
+
# locate all tables contained within the "table" passed in, which
# may be a join or other construct
if isinstance(self.polymorphic_map[key], type):
self.polymorphic_map[key] = class_mapper(self.polymorphic_map[key])
- l = [(key, prop) for key, prop in self.props.iteritems()]
- for key, prop in l:
- if getattr(prop, 'key', None) is None:
- prop.init(key, self)
-
# select_table specified...set up a surrogate mapper that will be used for selects
# select_table has to encompass all the columns of the mapped_table either directly
# or through proxying relationships
for key, prop in properties.iteritems():
if sql.is_column(prop):
props[key] = self.select_table.corresponding_column(prop)
- elif (isinstance(column, list) and sql.is_column(column[0])):
+ elif (isinstance(prop, list) and sql.is_column(prop[0])):
props[key] = [self.select_table.corresponding_column(c) for c in prop]
self.__surrogate_mapper = Mapper(self.class_, self.select_table, non_primary=True, properties=props, polymorphic_map=self.polymorphic_map, polymorphic_on=self.polymorphic_on)
+
+ l = [(key, prop) for key, prop in self.props.iteritems()]
+ for key, prop in l:
+ if getattr(prop, 'key', None) is None:
+ prop.init(key, self)
+
def base_mapper(self):
"""returns the ultimate base mapper in an inheritance chain"""
"""returns True if this mapper is the primary mapper for its class key (class + entity_name)"""
return mapper_registry.get(self.class_key, None) is self
- def _primary_mapper(self):
+ def primary_mapper(self):
"""returns the primary mapper corresponding to this mapper's class key (class + entity_name)"""
return mapper_registry[self.class_key]
def _setattrbycolumn(self, obj, column, value):
self.columntoproperty[column][0].setattr(obj, value)
- def primary_mapper(self):
- return mapper_registry[self.class_key]
def save_obj(self, objects, uow, postupdate=False):
"""called by a UnitOfWork object to save objects, which involves either an INSERT or
self.selectable = selectable
def __translate_col(self, col):
ourcol = self.selectable.corresponding_column(col, keys_ok=False, raiseerr=False)
+ #if col is not ourcol:
+ # print "TD TRANSLATING ", col, "TO", ourcol
if ourcol is None:
return col
else:
def do_init_subclass(self, key, parent):
"""template method for subclasses of PropertyLoader"""
pass
-
+
def do_init(self, key, parent):
import sqlalchemy.orm
if isinstance(self.argument, type):
return
if binary.left.primary_key:
if dependent[0] is binary.left.table:
- raise exceptions.ArgumentError("Could not determine the parent/child relationship for property '%s', based on join condition '%s' (table '%s' appears on both sides of the relationship, or in an otherwise ambiguous manner). please specify the 'foreignkey' keyword parameter to the relation() function indicating a column on the remote side of the relationship" % (self.key, str(self.primaryjoin), str(binary.left.table)))
+ raise exceptions.ArgumentError("Could not determine the parent/child relationship for property '%s', based on join condition '%s' (table '%s' appears on both sides of the relationship, or in an otherwise ambiguous manner). please specify the 'foreignkey' keyword parameter to the relation() function indicating a column on the remote side of the relationship" % (self.key, str(self.primaryjoin), binary.left.table.name))
dependent[0] = binary.right.table
self.foreignkey= binary.right
elif binary.right.primary_key:
if dependent[0] is binary.right.table:
- raise exceptions.ArgumentError("Could not determine the parent/child relationship for property '%s', based on join condition '%s' (table '%s' appears on both sides of the relationship, or in an otherwise ambiguous manner). please specify the 'foreignkey' keyword parameter to the relation() function indicating a column on the remote side of the relationship" % (self.key, str(self.primaryjoin), str(binary.right.table)))
+ raise exceptions.ArgumentError("Could not determine the parent/child relationship for property '%s', based on join condition '%s' (table '%s' appears on both sides of the relationship, or in an otherwise ambiguous manner). please specify the 'foreignkey' keyword parameter to the relation() function indicating a column on the remote side of the relationship" % (self.key, str(self.primaryjoin), binary.right.table.name))
dependent[0] = binary.left.table
self.foreignkey = binary.left
visitor = BinaryVisitor(foo)
self.primaryjoin.accept_visitor(visitor)
if dependent[0] is None:
- raise exceptions.ArgumentError("Could not determine the parent/child relationship for property '%s', based on join condition '%s' (no relationships joining tables '%s' and '%s' could be located). please specify the 'foreignkey' keyword parameter to the relation() function indicating a column on the remote side of the relationship" % (self.key, str(self.primaryjoin), str(binary.left.table), str(binary.right.table)))
+ raise exceptions.ArgumentError("Could not determine the parent/child relationship for property '%s', based on join condition '%s' (no relationships joining tables '%s' and '%s' could be located). please specify the 'foreignkey' keyword parameter to the relation() function indicating a column on the remote side of the relationship" % (self.key, str(self.primaryjoin), str(binary.left.table), binary.right.table.name))
else:
self.foreigntable = dependent[0]
PropertyLoader's mapper."""
# try to set a LazyLoader on our mapper referencing the parent mapper
mapper = prop.mapper.primary_mapper()
- if not prop.mapper.props.has_key(self.key):
+ if not mapper.props.has_key(self.key):
pj = self.kwargs.pop('primaryjoin', None)
sj = self.kwargs.pop('secondaryjoin', None)
# TODO: we are going to have the newly backref'd property create its
"""called by mapper.PropertyLoader to register the objects handled by
one mapper being dependent on the objects handled by another."""
# correct for primary mapper (the mapper offcially associated with the class)
- mapper = mapper._primary_mapper().base_mapper()
- dependency = dependency._primary_mapper().base_mapper()
+ mapper = mapper.primary_mapper().base_mapper()
+ dependency = dependency.primary_mapper().base_mapper()
self.dependencies[(mapper, dependency)] = True
self._mark_modified()
#print "registerprocessor", str(mapper), repr(processor.key), str(mapperfrom)
# correct for primary mapper (the mapper offcially associated with the class)
- mapper = mapper._primary_mapper()
- mapperfrom = mapperfrom._primary_mapper()
+ mapper = mapper.primary_mapper()
+ mapperfrom = mapperfrom.primary_mapper()
task = self.get_task_by_mapper(mapper)
targettask = self.get_task_by_mapper(mapperfrom)
self._execute_per_element_childtasks(trans, True)
self._delete_objects(trans)
+ def polymorphic_tasks(self):
+ yield self
+ for task in self.inheriting_tasks:
+ for t in task.polymorphic_tasks():
+ yield t
+
def contains_object(self, obj, polymorphic=False):
if obj in self.objects:
return True
return l
def dependency_in_cycles(dep):
- proctask = trans.get_task_by_mapper(dep.processor.mapper, True)
+ proctask = trans.get_task_by_mapper(dep.processor.mapper.primary_mapper(), True)
return dep.targettask in cycles and (proctask is not None and proctask in cycles)
# organize all original UOWDependencyProcessors by their target task
deps_by_targettask = {}
- for task in cycles:
- 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 task in cycles:
- for taskelement in task.get_elements(polymorphic=True):
- obj = taskelement.obj
- 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 ?
+ for t in cycles:
+ for task in t.polymorphic_tasks():
+ for dep in task.dependencies:
if not dependency_in_cycles(dep):
- continue
-
- (processor, targettask) = (dep.processor, dep.targettask)
- isdelete = taskelement.isdelete
+ extradeplist.append(dep)
+ l = deps_by_targettask.setdefault(dep.targettask, [])
+ l.append(dep)
+
+ for t in cycles:
+ for task in t.polymorphic_tasks():
+ for taskelement in task.get_elements(polymorphic=False):
+ obj = taskelement.obj
+ 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 ?
+ if not dependency_in_cycles(dep):
+ continue
+ #print "DEP", dep.processor.key
+ (processor, targettask) = (dep.processor, dep.targettask)
+ isdelete = taskelement.isdelete
- # list of dependent objects from this object
- childlist = dep.get_object_dependencies(obj, trans, passive = True)
+ # list of dependent objects from this object
+ childlist = dep.get_object_dependencies(obj, trans, passive = True)
- # the task corresponding to saving/deleting of those dependent objects
- childtask = trans.get_task_by_mapper(processor.mapper)
+ # the task corresponding to saving/deleting of those dependent objects
+ childtask = trans.get_task_by_mapper(processor.mapper.primary_mapper())
- childlist = childlist.added_items() + childlist.unchanged_items() + childlist.deleted_items()
+ childlist = childlist.added_items() + childlist.unchanged_items() + childlist.deleted_items()
- for o in childlist:
- if o is None or not childtask.contains_object(o, polymorphic=True):
- continue
- whosdep = dep.whose_dependent_on_who(obj, o)
- if whosdep is not None:
- tuples.append(whosdep)
- # create a UOWDependencyProcessor representing this pair of objects.
- # append it to a UOWTask
- if whosdep[0] is obj:
- get_dependency_task(whosdep[0], dep).append(whosdep[0], isdelete=isdelete)
+ for o in childlist:
+ if o is None or not childtask.contains_object(o, polymorphic=True):
+ continue
+ #print "CHILD", o
+ whosdep = dep.whose_dependent_on_who(obj, o)
+ if whosdep is not None:
+ tuples.append(whosdep)
+ # create a UOWDependencyProcessor representing this pair of objects.
+ # append it to a UOWTask
+ if whosdep[0] is obj:
+ get_dependency_task(whosdep[0], dep).append(whosdep[0], isdelete=isdelete)
+ else:
+ get_dependency_task(whosdep[0], dep).append(whosdep[1], isdelete=isdelete)
else:
- get_dependency_task(whosdep[0], dep).append(whosdep[1], isdelete=isdelete)
- else:
- get_dependency_task(obj, dep).append(obj, isdelete=isdelete)
-
+ get_dependency_task(obj, dep).append(obj, isdelete=isdelete)
+
+ #print "TUPLES", tuples
head = DependencySorter(tuples, allobjects).sort()
if head is None:
return None
can_add_to_parent = t.mapper is parenttask.mapper
original_task = object_to_original_task[node.item]
+ #print "ORIG TASK", original_task
if original_task.contains_object(node.item, polymorphic=False):
if can_add_to_parent:
parenttask.append(node.item, original_task.objects[node.item].listonly, isdelete=original_task.objects[node.item].isdelete, childtask=t)