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()
示例#2
0
 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
示例#3
0
    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()
示例#4
0
    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()
示例#5
0
    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
示例#6
0
 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()
示例#7
0
    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)
示例#8
0
    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)