def __init__(self, uow): self.uow = uow # unique list of all the mappers we come across self.mappers = util.HashSet() self.dependencies = {} self.tasks = {} self.saved_histories = util.HashSet()
def __init__(self, uow, session): self.uow = uow self.session = session # unique list of all the mappers we come across self.mappers = util.HashSet() self.dependencies = {} self.tasks = {} self.saved_histories = util.HashSet() self.__modified = False
def __init__(self, identity_map=None): if identity_map is not None: self.identity_map = identity_map else: self.identity_map = weakref.WeakValueDictionary() self.attributes = global_attributes self.new = util.HashSet(ordered=True) self.dirty = util.HashSet() self.modified_lists = util.HashSet() self.deleted = util.HashSet()
def flush(self, session, *objects): flush_context = UOWTransaction(self, session) if len(objects): objset = util.HashSet(iter=objects) else: objset = None for obj in [n for n in self.new] + [d for d in self.dirty]: if objset is not None and not objset.contains(obj): continue if self.deleted.contains(obj): continue flush_context.register_object(obj) for item in self.modified_lists: obj = item.obj if objset is not None and not objset.contains(obj): continue if self.deleted.contains(obj): continue flush_context.register_object(obj, listonly=True) flush_context.register_saved_history(item) # for o in item.added_items() + item.deleted_items(): # if self.deleted.contains(o): # continue # flush_context.register_object(o, listonly=True) for obj in self.deleted: if objset is not None and not objset.contains(obj): continue flush_context.register_object(obj, isdelete=True) engines = util.HashSet() for mapper in flush_context.mappers: for e in session.engines(mapper): engines.append(e) echo_commit = False for e in engines: echo_commit = echo_commit or e.echo_uow e.begin() try: flush_context.execute(echo=echo_commit) except: for e in engines: e.rollback() raise for e in engines: e.commit() flush_context.post_exec()
def _sort_dependencies(self): """creates a hierarchical tree of dependent tasks. the root node is returned. when the root node is executed, it also executes its child tasks recursively.""" def sort_hier(node): if node is None: return None task = self.get_task_by_mapper(node.item) if node.cycles is not None: tasks = [] for n in node.cycles: tasks.append(self.get_task_by_mapper(n.item)) task.circular = task._sort_circular_dependencies(self, tasks) for child in node.children: t = sort_hier(child) if t is not None: task.childtasks.append(t) return task mappers = util.HashSet() for task in self.tasks.values(): mappers.append(task.mapper) head = DependencySorter(self.dependencies, mappers).sort(allow_all_cycles=True) #print str(head) task = sort_hier(head) return task
def multi_transaction(self, tables, func): """provides a transaction boundary across tables which may be in multiple databases. If you have three tables, and a function that operates upon them, providing the tables as a list and the function will result in a begin()/commit() pair invoked for each distinct engine represented within those tables, and the function executed within the context of that transaction. any exceptions will result in a rollback(). clearly, this approach only goes so far, such as if database A commits, then database B commits and fails, A is already committed. Any failure conditions have to be raised before anyone commits for this to be useful.""" engines = util.HashSet() for table in tables: engines.append(table.engine) for engine in engines: engine.begin() try: func() except: for engine in engines: engine.rollback() raise for engine in engines: engine.commit()
def __init__(self, class_, table, primarytable=None, properties=None, primary_key=None, is_primary=False, inherits=None, inherit_condition=None, extension=None, order_by=False, allow_column_override=False, **kwargs): if primarytable is not None: sys.stderr.write( "'primarytable' argument to mapper is deprecated\n") if extension is None: self.extension = MapperExtension() else: self.extension = extension self.class_ = class_ self.is_primary = is_primary self.order_by = order_by self._options = {} if not issubclass(class_, object): raise TypeError("Class '%s' is not a new-style class" % class_.__name__) if isinstance(table, sql.Select): # 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 # we make, theres workarounds but it starts to get really crazy (its crazy enough # the SQL that gets generated) so just require an alias raise TypeError( "Mapping against a Select object requires that it has a name. Use an alias to give it a name, i.e. s = select(...).alias('myselect')" ) else: self.table = table if inherits is not None: self.primarytable = inherits.primarytable # inherit_condition is optional since the join can figure it out self.table = sql.join(inherits.table, table, inherit_condition) else: self.primarytable = self.table # locate all tables contained within the "table" passed in, which # may be a join or other construct tf = TableFinder() self.table.accept_visitor(tf) self.tables = tf.tables # determine primary key columns, either passed in, or get them from our set of tables self.pks_by_table = {} if primary_key is not None: for k in primary_key: self.pks_by_table.setdefault( k.table, util.HashSet(ordered=True)).append(k) if k.table != self.table: # associate pk cols from subtables to the "main" table self.pks_by_table.setdefault( self.table, util.HashSet(ordered=True)).append(k) else: for t in self.tables + [self.table]: try: l = self.pks_by_table[t] except KeyError: l = self.pks_by_table.setdefault( t, util.HashSet(ordered=True)) if not len(t.primary_key): raise ValueError( "Table " + t.name + " has no primary key columns. Specify primary_key argument to mapper." ) for k in t.primary_key: l.append(k) # make table columns addressable via the mapper self.columns = util.OrderedProperties() self.c = self.columns # object attribute names mapped to MapperProperty objects self.props = {} # table columns mapped to lists of MapperProperty objects # using a list allows a single column to be defined as # populating multiple object attributes self.columntoproperty = {} # load custom properties if properties is not None: for key, prop in properties.iteritems(): if sql.is_column(prop): try: prop = self.table._get_col_by_original(prop) except KeyError: raise ValueError( "Column '%s' is not represented in mapper's table" % prop._label) self.columns[key] = prop prop = ColumnProperty(prop) elif isinstance(prop, list) and sql.is_column(prop[0]): try: prop = [ self.table._get_col_by_original(p) for p in prop ] except KeyError, e: raise ValueError( "Column '%s' is not represented in mapper's table" % e.args[0]) self.columns[key] = prop[0] prop = ColumnProperty(*prop) self.props[key] = prop if isinstance(prop, ColumnProperty): for col in prop.columns: proplist = self.columntoproperty.setdefault( col.original, []) proplist.append(prop)
def __init__(self, class_, table, primarytable=None, properties=None, primary_key=None, is_primary=False, inherits=None, inherit_condition=None, extension=None, order_by=False, allow_column_override=False, entity_name=None, always_refresh=False, version_id_col=None, construct_new=False, **kwargs): if primarytable is not None: sys.stderr.write( "'primarytable' argument to mapper is deprecated\n") ext = MapperExtension() for ext_class in global_extensions: ext = ext_class().chain(ext) if extension is not None: for ext_obj in util.to_list(extension): ext = ext_obj.chain(ext) self.extension = ext self.class_ = class_ self.entity_name = entity_name self.class_key = ClassKey(class_, entity_name) self.is_primary = is_primary self.order_by = order_by self._options = {} self.always_refresh = always_refresh self.version_id_col = version_id_col self.construct_new = construct_new if not issubclass(class_, object): raise ArgumentError("Class '%s' is not a new-style class" % class_.__name__) if isinstance(table, sql.Select): # 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 # we make, theres workarounds but it starts to get really crazy (its crazy enough # the SQL that gets generated) so just require an alias raise ArgumentError( "Mapping against a Select object requires that it has a name. Use an alias to give it a name, i.e. s = select(...).alias('myselect')" ) else: self.table = table if inherits is not None: if self.class_.__mro__[1] != inherits.class_: raise ArgumentError( "Class '%s' does not inherit from '%s'" % (self.class_.__name__, inherits.class_.__name__)) self.primarytable = inherits.primarytable # inherit_condition is optional. if not table is inherits.noninherited_table: if inherit_condition is None: # figure out inherit condition from our table to the immediate table # of the inherited mapper, not its full table which could pull in other # stuff we dont want (allows test/inheritance.InheritTest4 to pass) inherit_condition = sql.join(inherits.noninherited_table, table).onclause self.table = sql.join(inherits.table, table, inherit_condition) #print "inherit condition", str(self.table.onclause) # generate sync rules. similarly to creating the on clause, specify a # stricter set of tables to create "sync rules" by,based on the immediate # inherited table, rather than all inherited tables self._synchronizer = sync.ClauseSynchronizer( self, self, sync.ONETOMANY) self._synchronizer.compile( self.table.onclause, util.HashSet([inherits.noninherited_table]), mapperutil.TableFinder(table)) # the old rule #self._synchronizer.compile(self.table.onclause, inherits.tables, TableFinder(table)) else: self._synchronizer = None self.inherits = inherits self.noninherited_table = table if self.order_by is False: self.order_by = inherits.order_by else: self.primarytable = self.table self.noninherited_table = self.table self._synchronizer = None self.inherits = None # locate all tables contained within the "table" passed in, which # may be a join or other construct self.tables = mapperutil.TableFinder(self.table) # determine primary key columns, either passed in, or get them from our set of tables self.pks_by_table = {} if primary_key is not None: for k in primary_key: self.pks_by_table.setdefault( k.table, util.HashSet(ordered=True)).append(k) if k.table != self.table: # associate pk cols from subtables to the "main" table self.pks_by_table.setdefault( self.table, util.HashSet(ordered=True)).append(k) else: for t in self.tables + [self.table]: try: l = self.pks_by_table[t] except KeyError: l = self.pks_by_table.setdefault( t, util.HashSet(ordered=True)) if not len(t.primary_key): raise ArgumentError( "Table " + t.name + " has no primary key columns. Specify primary_key argument to mapper." ) for k in t.primary_key: l.append(k) # make table columns addressable via the mapper self.columns = util.OrderedProperties() self.c = self.columns # object attribute names mapped to MapperProperty objects self.props = {} # table columns mapped to lists of MapperProperty objects # using a list allows a single column to be defined as # populating multiple object attributes self.columntoproperty = {} # load custom properties if properties is not None: for key, prop in properties.iteritems(): if sql.is_column(prop): try: prop = self.table._get_col_by_original(prop) except KeyError: raise ArgumentError( "Column '%s' is not represented in mapper's table" % prop._label) self.columns[key] = prop prop = ColumnProperty(prop) elif isinstance(prop, list) and sql.is_column(prop[0]): try: prop = [ self.table._get_col_by_original(p) for p in prop ] except KeyError, e: raise ArgumentError( "Column '%s' is not represented in mapper's table" % e.args[0]) self.columns[key] = prop[0] prop = ColumnProperty(*prop) self.props[key] = prop if isinstance(prop, ColumnProperty): for col in prop.columns: proplist = self.columntoproperty.setdefault( col.original, []) proplist.append(prop)