Exemplo n.º 1
0
    def get_bind(self, mapper, clause=None, **kwargs):
        """Return an engine corresponding to the given arguments.

        mapper
            mapper relative to the desired operation

        clause
            a ClauseElement which is to be executed.  if
            mapper is not present, this may be used to locate
            Table objects, which are then associated with mappers
            which have associated binds.

        \**kwargs
            Subclasses (i.e. ShardedSession) may add additional arguments
            to get_bind() which are passed through here.
        """

        if mapper is None and clause is None:
            if self.bind is not None:
                return self.bind
            else:
                raise exceptions.UnboundExecutionError(
                    "This session is unbound to any Engine or Connection; specify a mapper to get_bind()"
                )

        elif len(self.__binds):
            if mapper is not None:
                if isinstance(mapper, type):
                    mapper = _class_mapper(mapper)
                if mapper.base_mapper in self.__binds:
                    return self.__binds[mapper.base_mapper]
                elif mapper.compile().mapped_table in self.__binds:
                    return self.__binds[mapper.mapped_table]
            if clause is not None:
                for t in clause._table_iterator():
                    if t in self.__binds:
                        return self.__binds[t]

        if self.bind is not None:
            return self.bind
        elif isinstance(clause, sql.expression.ClauseElement) and clause.bind is not None:
            return clause.bind
        elif mapper is None:
            raise exceptions.UnboundExecutionError("Could not locate any mapper associated with SQL expression")
        else:
            if isinstance(mapper, type):
                mapper = _class_mapper(mapper)
            else:
                mapper = mapper.compile()
            e = mapper.mapped_table.bind
            if e is None:
                raise exceptions.UnboundExecutionError(
                    "Could not locate any Engine or Connection bound to mapper '%s'" % str(mapper)
                )
            return e
Exemplo n.º 2
0
    def get_bind(self, mapper, clause=None, **kwargs):
        """return an engine corresponding to the given arguments.
        
            mapper
                mapper relative to the desired operation
            
            clause
                a ClauseElement which is to be executed.  if
                mapper is not present, this may be used to locate
                Table objects, which are then associated with mappers
                which have associated binds.
                
            \**kwargs
                Subclasses (i.e. ShardedSession) may add additional arguments 
                to get_bind() which are passed through here.
        """

        if mapper is None and clause is None:
            if self.bind is not None:
                return self.bind
            else:
                raise exceptions.InvalidRequestError(
                    "This session is unbound to any Engine or Connection; specify a mapper to get_bind()"
                )

        elif len(self.__binds):
            if mapper is not None:
                if isinstance(mapper, type):
                    mapper = _class_mapper(mapper)
                if mapper.base_mapper in self.__binds:
                    return self.__binds[mapper.base_mapper]
                elif mapper.compile().mapped_table in self.__binds:
                    return self.__binds[mapper.mapped_table]
            if clause is not None:
                for t in clause._table_iterator():
                    if t in self.__binds:
                        return self.__binds[t]

        if self.bind is not None:
            return self.bind
        else:
            if isinstance(mapper, type):
                mapper = _class_mapper(mapper)
            else:
                mapper = mapper.compile()
            e = mapper.mapped_table.bind
            if e is None:
                raise exceptions.InvalidRequestError(
                    "Could not locate any Engine or Connection bound to mapper '%s'"
                    % str(mapper))
            return e
Exemplo n.º 3
0
 def connection(self, mapper_or_class, entity_name=None):
     if isinstance(mapper_or_class, type):
         mapper_or_class = _class_mapper(mapper_or_class, entity_name=entity_name)
     if self.parent is not None:
         return self.parent.connection(mapper_or_class)
     engine = self.session.get_bind(mapper_or_class)
     return self.get_or_add(engine)
Exemplo n.º 4
0
    def identity_key(self, *args, **kwargs):
        """Get an identity key.

        Valid call signatures:

            identity_key(class\_, ident, entity_name=None)
                class\_
                    mapped class (must be a positional argument)

                ident
                    primary key, if the key is composite this is a tuple
                
                entity_name
                    optional entity name

            identity_key(instance=instance)
                instance
                    object instance (must be given as a keyword arg)

            identity_key(class\_, row=row, entity_name=None)
                class\_
                    mapped class (must be a positional argument)
                
                row
                    result proxy row (must be given as a keyword arg)

                entity_name
                    optional entity name (must be given as a keyword arg)
        """
        if args:
            if len(args) == 1:
                class_ = args[0]
                try:
                    row = kwargs.pop("row")
                except KeyError:
                    ident = kwargs.pop("ident")
                entity_name = kwargs.pop("entity_name", None)
            elif len(args) == 2:
                class_, ident = args
                entity_name = kwargs.pop("entity_name", None)
            elif len(args) == 3:
                class_, ident, entity_name = args
            else:
                raise exceptions.ArgumentError("expected up to three "
                                               "positional arguments, got %s" %
                                               len(args))
            if kwargs:
                raise exceptions.ArgumentError(
                    "unknown keyword arguments: %s" % ", ".join(kwargs.keys()))
            mapper = _class_mapper(class_, entity_name=entity_name)
            if "ident" in locals():
                return mapper.identity_key_from_primary_key(ident)
            return mapper.identity_key_from_row(row)
        instance = kwargs.pop("instance")
        if kwargs:
            raise exceptions.ArgumentError("unknown keyword arguments: %s" %
                                           ", ".join(kwargs.keys()))
        mapper = _object_mapper(instance)
        return mapper.identity_key_from_instance(instance)
Exemplo n.º 5
0
    def identity_key(cls, *args, **kwargs):
        """Get an identity key.

        Valid call signatures:

        * ``identity_key(class, ident, entity_name=None)``

          class
              mapped class (must be a positional argument)

          ident
              primary key, if the key is composite this is a tuple

          entity_name
              optional entity name

        * ``identity_key(instance=instance)``

          instance
              object instance (must be given as a keyword arg)

        * ``identity_key(class, row=row, entity_name=None)``

          class
              mapped class (must be a positional argument)

          row
              result proxy row (must be given as a keyword arg)

          entity_name
              optional entity name (must be given as a keyword arg)
        """

        if args:
            if len(args) == 1:
                class_ = args[0]
                try:
                    row = kwargs.pop("row")
                except KeyError:
                    ident = kwargs.pop("ident")
                entity_name = kwargs.pop("entity_name", None)
            elif len(args) == 2:
                class_, ident = args
                entity_name = kwargs.pop("entity_name", None)
            elif len(args) == 3:
                class_, ident, entity_name = args
            else:
                raise exceptions.ArgumentError("expected up to three " "positional arguments, got %s" % len(args))
            if kwargs:
                raise exceptions.ArgumentError("unknown keyword arguments: %s" % ", ".join(kwargs.keys()))
            mapper = _class_mapper(class_, entity_name=entity_name)
            if "ident" in locals():
                return mapper.identity_key_from_primary_key(ident)
            return mapper.identity_key_from_row(row)
        instance = kwargs.pop("instance")
        if kwargs:
            raise exceptions.ArgumentError("unknown keyword arguments: %s" % ", ".join(kwargs.keys()))
        mapper = _object_mapper(instance)
        return mapper.identity_key_from_instance(instance)
Exemplo n.º 6
0
 def query(self, mapper_or_class, entity_name=None, **kwargs):
     """return a new Query object corresponding to this Session and the mapper, or the classes' primary mapper."""
     if isinstance(mapper_or_class, type):
         return query.Query(
             _class_mapper(mapper_or_class, entity_name=entity_name), self,
             **kwargs)
     else:
         return query.Query(mapper_or_class, self, **kwargs)
Exemplo n.º 7
0
 def connection(self, mapper_or_class, entity_name=None):
     if isinstance(mapper_or_class, type):
         mapper_or_class = _class_mapper(mapper_or_class,
                                         entity_name=entity_name)
     if self.parent is not None:
         return self.parent.connection(mapper_or_class)
     engine = self.session.get_bind(mapper_or_class)
     return self.get_or_add(engine)
Exemplo n.º 8
0
Arquivo: session.py Projeto: serah/HR
    def merge(self, instance, entity_name=None, dont_load=False, _recursive=None):
        """Copy the state of the given `instance` onto the persistent
        instance with the same identifier.

        If there is no persistent instance currently associated with
        the session, it will be loaded.  Return the persistent
        instance. If the given instance is unsaved, save a copy of and
        return it as a newly persistent instance. The given instance
        does not become associated with the session.

        This operation cascades to associated instances if the
        association is mapped with ``cascade="merge"``.
        """

        if _recursive is None:
            _recursive = {}  # TODO: this should be an IdentityDict for instances, but will need a separate
                             # dict for PropertyLoader tuples
        if entity_name is not None:
            mapper = _class_mapper(instance.__class__, entity_name=entity_name)
        else:
            mapper = _object_mapper(instance)
        if instance in _recursive:
            return _recursive[instance]

        key = getattr(instance, '_instance_key', None)
        if key is None:
            if dont_load:
                raise exceptions.InvalidRequestError("merge() with dont_load=True option does not support objects transient (i.e. unpersisted) objects.  flush() all changes on mapped instances before merging with dont_load=True.")
            key = mapper.identity_key_from_instance(instance)

        merged = None
        if key:
            if key in self.identity_map:
                merged = self.identity_map[key]
            elif dont_load:
                if instance._state.modified:
                    raise exceptions.InvalidRequestError("merge() with dont_load=True option does not support objects marked as 'dirty'.  flush() all changes on mapped instances before merging with dont_load=True.")

                merged = attributes.new_instance(mapper.class_)
                merged._instance_key = key
                merged._entity_name = entity_name
                self._update_impl(merged, entity_name=mapper.entity_name)
            else:
                merged = self.get(mapper.class_, key[1])
        
        if merged is None:
            merged = attributes.new_instance(mapper.class_)
            self.save(merged, entity_name=mapper.entity_name)
            
        _recursive[instance] = merged
        
        for prop in mapper.iterate_properties:
            prop.merge(self, instance, merged, dont_load, _recursive)
            
        if dont_load:
            merged._state.commit_all()  # remove any history

        return merged
Exemplo n.º 9
0
Arquivo: session.py Projeto: serah/HR
    def bind_mapper(self, mapper, bind, entity_name=None):
        """Bind the given `mapper` or `class` to the given ``Engine`` or ``Connection``.

        All subsequent operations involving this ``Mapper`` will use the
        given `bind`.
        """

        if isinstance(mapper, type):
            mapper = _class_mapper(mapper, entity_name=entity_name)

        self.__binds[mapper.base_mapper] = bind
        for t in mapper._all_tables:
            self.__binds[t] = bind
Exemplo n.º 10
0
    def bind_mapper(self, mapper, bind, entity_name=None):
        """Bind the given `mapper` or `class` to the given ``Engine`` or ``Connection``.

        All subsequent operations involving this ``Mapper`` will use the
        given `bind`.
        """

        if isinstance(mapper, type):
            mapper = _class_mapper(mapper, entity_name=entity_name)

        self.__binds[mapper.base_mapper] = bind
        for t in mapper._all_tables:
            self.__binds[t] = bind
Exemplo n.º 11
0
    def _save_impl(self, object, **kwargs):
        if hasattr(object, '_instance_key'):
            if not self.identity_map.has_key(object._instance_key):
                raise exceptions.InvalidRequestError("Instance '%s' is a detached instance or is already persistent in a different Session" % repr(object))
        else:
            m = _class_mapper(object.__class__, entity_name=kwargs.get('entity_name', None))

            # this would be a nice exception to raise...however this is incompatible with a contextual
            # session which puts all objects into the session upon construction.
            #if m._is_orphan(object):
            #    raise exceptions.InvalidRequestError("Instance '%s' is an orphan, and must be attached to a parent object to be saved" % (repr(object)))

            m._assign_entity_name(object)
            self._register_pending(object)
Exemplo n.º 12
0
Arquivo: session.py Projeto: serah/HR
    def query(self, mapper_or_class, *addtl_entities, **kwargs):
        """Return a new ``Query`` object corresponding to this ``Session`` and
        the mapper, or the classes' primary mapper.

        """
        entity_name = kwargs.pop('entity_name', None)

        if isinstance(mapper_or_class, type):
            q = self._query_cls(_class_mapper(mapper_or_class, entity_name=entity_name), self, **kwargs)
        else:
            q = self._query_cls(mapper_or_class, self, **kwargs)

        for ent in addtl_entities:
            q = q.add_entity(ent)
        return q
Exemplo n.º 13
0
    def _save_impl(self, object, **kwargs):
        if hasattr(object, '_instance_key'):
            if not self.identity_map.has_key(object._instance_key):
                raise exceptions.InvalidRequestError(
                    "Instance '%s' is a detached instance or is already persistent in a different Session"
                    % repr(object))
        else:
            m = _class_mapper(object.__class__,
                              entity_name=kwargs.get('entity_name', None))

            # this would be a nice exception to raise...however this is incompatible with a contextual
            # session which puts all objects into the session upon construction.
            #if m._is_orphan(object):
            #    raise exceptions.InvalidRequestError("Instance '%s' is an orphan, and must be attached to a parent object to be saved" % (repr(object)))

            m._assign_entity_name(object)
            self._register_pending(object)
Exemplo n.º 14
0
    def query(self, mapper_or_class, *addtl_entities, **kwargs):
        """Return a new ``Query`` object corresponding to this ``Session`` and
        the mapper, or the classes' primary mapper.
        """

        entity_name = kwargs.pop('entity_name', None)

        if isinstance(mapper_or_class, type):
            q = self._query_cls(
                _class_mapper(mapper_or_class, entity_name=entity_name), self,
                **kwargs)
        else:
            q = self._query_cls(mapper_or_class, self, **kwargs)

        for ent in addtl_entities:
            q = q.add_entity(ent)
        return q
Exemplo n.º 15
0
    def merge(self, object, entity_name=None, _recursive=None):
        """Copy the state of the given `object` onto the persistent
        object with the same identifier.

        If there is no persistent instance currently associated with
        the session, it will be loaded.  Return the persistent
        instance. If the given instance is unsaved, save a copy of and
        return it as a newly persistent instance. The given instance
        does not become associated with the session.

        This operation cascades to associated instances if the
        association is mapped with ``cascade="merge"``.
        """

        if _recursive is None:
            _recursive = util.Set()
        if entity_name is not None:
            mapper = _class_mapper(object.__class__, entity_name=entity_name)
        else:
            mapper = _object_mapper(object)
        if mapper in _recursive or object in _recursive:
            return None
        _recursive.add(mapper)
        _recursive.add(object)
        try:
            key = getattr(object, '_instance_key', None)
            if key is None:
                merged = attribute_manager.new_instance(mapper.class_)
            else:
                if key in self.identity_map:
                    merged = self.identity_map[key]
                else:
                    merged = self.get(mapper.class_, key[1])
                    if merged is None:
                        raise exceptions.AssertionError(
                            "Instance %s has an instance key but is not persisted"
                            % mapperutil.instance_str(object))
            for prop in mapper.iterate_properties:
                prop.merge(self, object, merged, _recursive)
            if key is None:
                self.save(merged, entity_name=mapper.entity_name)
            return merged
        finally:
            _recursive.remove(mapper)
Exemplo n.º 16
0
    def merge(self, object, entity_name=None, _recursive=None):
        """Copy the state of the given `object` onto the persistent
        object with the same identifier.

        If there is no persistent instance currently associated with
        the session, it will be loaded.  Return the persistent
        instance. If the given instance is unsaved, save a copy of and
        return it as a newly persistent instance. The given instance
        does not become associated with the session.

        This operation cascades to associated instances if the
        association is mapped with ``cascade="merge"``.
        """

        if _recursive is None:
            _recursive = util.Set()
        if entity_name is not None:
            mapper = _class_mapper(object.__class__, entity_name=entity_name)
        else:
            mapper = _object_mapper(object)
        if mapper in _recursive or object in _recursive:
            return None
        _recursive.add(mapper)
        _recursive.add(object)
        try:
            key = getattr(object, '_instance_key', None)
            if key is None:
                merged = mapper._create_instance(self)
            else:
                if key in self.identity_map:
                    merged = self.identity_map[key]
                else:
                    merged = self.get(mapper.class_, key[1])
                    if merged is None:
                        raise exceptions.AssertionError("Instance %s has an instance key but is not persisted" % mapperutil.instance_str(object))
            for prop in mapper.props.values():
                prop.merge(self, object, merged, _recursive)
            if key is None:
                self.save(merged, entity_name=mapper.entity_name)
            return merged
        finally:
            _recursive.remove(mapper)
Exemplo n.º 17
0
 def query(self, mapper_or_class, entity_name=None, **kwargs):
     """return a new Query object corresponding to this Session and the mapper, or the classes' primary mapper."""
     if isinstance(mapper_or_class, type):
         return query.Query(_class_mapper(mapper_or_class, entity_name=entity_name), self, **kwargs)
     else:
         return query.Query(mapper_or_class, self, **kwargs)
Exemplo n.º 18
0
    def mapper(self, class_, entity_name=None):
        """Given a ``Class``, return the primary ``Mapper`` responsible for
        persisting it."""

        return _class_mapper(class_, entity_name = entity_name)
Exemplo n.º 19
0
    def mapper(self, class_, entity_name=None):
        """Given an Class, return the primary Mapper responsible for
        persisting it."""

        return _class_mapper(class_, entity_name=entity_name)
Exemplo n.º 20
0
    def __init__(self,
                 bind=None,
                 autoflush=True,
                 transactional=False,
                 twophase=False,
                 echo_uow=False,
                 weak_identity_map=True,
                 binds=None,
                 extension=None):
        """Construct a new Session.

            autoflush
                when ``True``, all query operations will issue a ``flush()`` call to this
                ``Session`` before proceeding. This is a convenience feature so that
                ``flush()`` need not be called repeatedly in order for database queries to
                retrieve results. It's typical that ``autoflush`` is used in conjunction with
                ``transactional=True``, so that ``flush()`` is never called; you just call
                ``commit()`` when changes are complete to finalize all changes to the
                database.
        
            bind
                an optional ``Engine`` or ``Connection`` to which this ``Session`` should be
                bound. When specified, all SQL operations performed by this session will
                execute via this connectable.
                
            binds
                an optional dictionary, which contains more granular "bind" information than
                the ``bind`` parameter provides. This dictionary can map individual ``Table``
                instances as well as ``Mapper`` instances to individual ``Engine`` or
                ``Connection`` objects. Operations which proceed relative to a particular
                ``Mapper`` will consult this dictionary for the direct ``Mapper`` instance as
                well as the mapper's ``mapped_table`` attribute in order to locate an
                connectable to use. The full resolution is described in the ``get_bind()``
                method of ``Session``. Usage looks like::
                
                    sess = Session(binds={
                        SomeMappedClass : create_engine('postgres://engine1'),
                        somemapper : create_engine('postgres://engine2'),
                        some_table : create_engine('postgres://engine3'),
                    })
                    
                Also see the ``bind_mapper()`` and ``bind_table()`` methods.
            
            echo_uow
                When ``True``, configure Python logging to dump all unit-of-work
                transactions. This is the equivalent of
                ``logging.getLogger('sqlalchemy.orm.unitofwork').setLevel(logging.DEBUG)``.
            
            extension
                an optional [sqlalchemy.orm.session#SessionExtension] instance, which will receive
                pre- and post- commit and flush events, as well as a post-rollback event.  User-
                defined code may be placed within these hooks using a user-defined subclass
                of ``SessionExtension``.
                
            transactional
                Set up this ``Session`` to automatically begin transactions. Setting this
                flag to ``True`` is the rough equivalent of calling ``begin()`` after each
                ``commit()`` operation, after each ``rollback()``, and after each
                ``close()``. Basically, this has the effect that all session operations are
                performed within the context of a transaction. Note that the ``begin()``
                operation does not immediately utilize any connection resources; only when
                connection resources are first required do they get allocated into a
                transactional context.

            twophase
                when ``True``, all transactions will be started using
                [sqlalchemy.engine_TwoPhaseTransaction]. During a ``commit()``, after
                ``flush()`` has been issued for all attached databaes, the ``prepare()``
                method on each database's ``TwoPhaseTransaction`` will be called. This allows
                each database to roll back the entire transaction, before each transaction is
                committed.

            weak_identity_map
                When set to the default value of ``False``, a weak-referencing map is used;
                instances which are not externally referenced will be garbage collected
                immediately. For dereferenced instances which have pending changes present,
                the attribute management system will create a temporary strong-reference to
                the object which lasts until the changes are flushed to the database, at which
                point it's again dereferenced. Alternatively, when using the value ``True``,
                the identity map uses a regular Python dictionary to store instances. The
                session will maintain all instances present until they are removed using
                expunge(), clear(), or purge().
        """
        self.echo_uow = echo_uow
        self.weak_identity_map = weak_identity_map
        self.uow = unitofwork.UnitOfWork(self)
        self.identity_map = self.uow.identity_map

        self.bind = bind
        self.__binds = {}
        self.transaction = None
        self.hash_key = id(self)
        self.autoflush = autoflush
        self.transactional = transactional
        self.twophase = twophase
        self.extension = extension
        self._query_cls = query.Query
        self._mapper_flush_opts = {}

        if binds is not None:
            for mapperortable, value in binds.iteritems():
                if isinstance(mapperortable, type):
                    mapperortable = _class_mapper(mapperortable).base_mapper
                self.__binds[mapperortable] = value
                if isinstance(mapperortable, Mapper):
                    for t in mapperortable._all_tables:
                        self.__binds[t] = value

        if self.transactional:
            self.begin()
        _sessions[self.hash_key] = self
Exemplo n.º 21
0
Arquivo: session.py Projeto: serah/HR
    def __init__(self, bind=None, autoflush=True, transactional=False, twophase=False, echo_uow=False, weak_identity_map=True, binds=None, extension=None):
        """Construct a new Session.
        
        A session is usually constructed using the [sqlalchemy.orm#create_session()] function, 
        or its more "automated" variant [sqlalchemy.orm#sessionmaker()].

        autoflush
            When ``True``, all query operations will issue a ``flush()`` call to this
            ``Session`` before proceeding. This is a convenience feature so that
            ``flush()`` need not be called repeatedly in order for database queries to
            retrieve results. It's typical that ``autoflush`` is used in conjunction with
            ``transactional=True``, so that ``flush()`` is never called; you just call
            ``commit()`` when changes are complete to finalize all changes to the
            database.

        bind
            An optional ``Engine`` or ``Connection`` to which this ``Session`` should be
            bound. When specified, all SQL operations performed by this session will
            execute via this connectable.

        binds
            An optional dictionary, which contains more granular "bind" information than
            the ``bind`` parameter provides. This dictionary can map individual ``Table``
            instances as well as ``Mapper`` instances to individual ``Engine`` or
            ``Connection`` objects. Operations which proceed relative to a particular
            ``Mapper`` will consult this dictionary for the direct ``Mapper`` instance as
            well as the mapper's ``mapped_table`` attribute in order to locate an
            connectable to use. The full resolution is described in the ``get_bind()``
            method of ``Session``. Usage looks like::

                sess = Session(binds={
                    SomeMappedClass : create_engine('postgres://engine1'),
                    somemapper : create_engine('postgres://engine2'),
                    some_table : create_engine('postgres://engine3'),
                })

            Also see the ``bind_mapper()`` and ``bind_table()`` methods.

        echo_uow
            When ``True``, configure Python logging to dump all unit-of-work
            transactions. This is the equivalent of
            ``logging.getLogger('sqlalchemy.orm.unitofwork').setLevel(logging.DEBUG)``.

        extension
            An optional [sqlalchemy.orm.session#SessionExtension] instance, which will receive
            pre- and post- commit and flush events, as well as a post-rollback event.  User-
            defined code may be placed within these hooks using a user-defined subclass
            of ``SessionExtension``.

        transactional
            Set up this ``Session`` to automatically begin transactions. Setting this
            flag to ``True`` is the rough equivalent of calling ``begin()`` after each
            ``commit()`` operation, after each ``rollback()``, and after each
            ``close()``. Basically, this has the effect that all session operations are
            performed within the context of a transaction. Note that the ``begin()``
            operation does not immediately utilize any connection resources; only when
            connection resources are first required do they get allocated into a
            transactional context.

        twophase
            When ``True``, all transactions will be started using
            [sqlalchemy.engine_TwoPhaseTransaction]. During a ``commit()``, after
            ``flush()`` has been issued for all attached databases, the ``prepare()``
            method on each database's ``TwoPhaseTransaction`` will be called. This allows
            each database to roll back the entire transaction, before each transaction is
            committed.

        weak_identity_map
            When set to the default value of ``False``, a weak-referencing map is used;
            instances which are not externally referenced will be garbage collected
            immediately. For dereferenced instances which have pending changes present,
            the attribute management system will create a temporary strong-reference to
            the object which lasts until the changes are flushed to the database, at which
            point it's again dereferenced. Alternatively, when using the value ``True``,
            the identity map uses a regular Python dictionary to store instances. The
            session will maintain all instances present until they are removed using
            expunge(), clear(), or purge().
        """
        self.echo_uow = echo_uow
        self.weak_identity_map = weak_identity_map
        self.uow = unitofwork.UnitOfWork(self)
        self.identity_map = self.uow.identity_map

        self.bind = bind
        self.__binds = {}
        self.transaction = None
        self.hash_key = id(self)
        self.autoflush = autoflush
        self.transactional = transactional
        self.twophase = twophase
        self.extension = extension
        self._query_cls = query.Query
        self._mapper_flush_opts = {}

        if binds is not None:
            for mapperortable, value in binds.iteritems():
                if isinstance(mapperortable, type):
                    mapperortable = _class_mapper(mapperortable).base_mapper
                self.__binds[mapperortable] = value
                if isinstance(mapperortable, Mapper):
                    for t in mapperortable._all_tables:
                        self.__binds[t] = value

        if self.transactional:
            self.begin()
        _sessions[self.hash_key] = self