예제 #1
0
파일: scoping.py 프로젝트: MaxMorais/skink
 def __init__(self, session_factory, scopefunc=None):
     self.session_factory = session_factory
     if scopefunc:
         self.registry = ScopedRegistry(session_factory, scopefunc)
     else:
         self.registry = ThreadLocalRegistry(session_factory)
     self.extension = _ScopedExt(self)
예제 #2
0
 def __init__(self, session_factory, scopefunc=None):
     self.session_factory = session_factory
     if scopefunc:
         self.registry = ScopedRegistry(session_factory, scopefunc)
     else:
         self.registry = ThreadLocalRegistry(session_factory)
     self.extension = _ScopedExt(self)
예제 #3
0
def init(connection_uri, echo=False, scopefunc=None):
    """Initialize the session.

    Args:
        connection_uri (str): The connection uri, such as
            "postgrseql://*****:*****@localhost/dbname"
        echo (bool): Echo SQL statements to stdout.  Useful for debugging.
        scopefunc (func): Optional function which defines
            the current scope.  See
            http://docs.sqlalchemy.org/en/latest/orm/contextual.html#sqlalchemy.orm.scoping.scoped_session.__init__
            for more information.  If this is not passed, the "thread-local"
            scope will be assumed.
    """
    global engine, session

    from frf.models import Model

    if 'postgres' in connection_uri:
        engine = create_engine(connection_uri,
                               echo=echo,
                               json_serializer=serialize,
                               json_deserializer=deserialize)
    else:
        engine = create_engine(connection_uri, echo=echo)

    if scopefunc is not None:
        session.registry = ScopedRegistry(session.session_factory,
                                          scopefunc=scopefunc)
    else:
        session.registry = ThreadLocalRegistry(session.session_factory)

    session.configure(bind=engine)
    Model.query = _QueryProperty(session)
예제 #4
0
    def __init__(self, session_factory, scopefunc=None):
        """Construct a new :class:`.scoped_session`.

        :param session_factory: a factory to create new :class:`.Session`
         instances. This is usually, but not necessarily, an instance
         of :class:`.sessionmaker`.
        :param scopefunc: optional function which defines
         the current scope.   If not passed, the :class:`.scoped_session`
         object assumes "thread-local" scope, and will use
         a Python ``threading.local()`` in order to maintain the current
         :class:`.Session`.  If passed, the function should return
         a hashable token; this token will be used as the key in a
         dictionary in order to store and retrieve the current
         :class:`.Session`.

        """
        self.session_factory = session_factory

        if scopefunc:
            self.registry = ScopedRegistry(session_factory, scopefunc)
        else:
            self.registry = ThreadLocalRegistry(session_factory)
예제 #5
0
class ScopedSession(object):
    """Provides thread-local management of Sessions.

    Typical invocation is via the :func:`.scoped_session`
    function::

      Session = scoped_session(sessionmaker())

    The internal registry is accessible,
    and by default is an instance of :class:`.ThreadLocalRegistry`.

    See also: :ref:`unitofwork_contextual`.

    """
    def __init__(self, session_factory, scopefunc=None):
        self.session_factory = session_factory
        if scopefunc:
            self.registry = ScopedRegistry(session_factory, scopefunc)
        else:
            self.registry = ThreadLocalRegistry(session_factory)

    def __call__(self, **kwargs):
        if kwargs:
            scope = kwargs.pop('scope', False)
            if scope is not None:
                if self.registry.has():
                    raise sa_exc.InvalidRequestError(
                        "Scoped session is already present; "
                        "no new arguments may be specified.")
                else:
                    sess = self.session_factory(**kwargs)
                    self.registry.set(sess)
                    return sess
            else:
                return self.session_factory(**kwargs)
        else:
            return self.registry()

    def remove(self):
        """Dispose of the current contextual session."""

        if self.registry.has():
            self.registry().close()
        self.registry.clear()

    def configure(self, **kwargs):
        """reconfigure the sessionmaker used by this ScopedSession."""

        if self.registry.has():
            warn('At least one scoped session is already present. '
                 ' configure() can not affect sessions that have '
                 'already been created.')

        self.session_factory.configure(**kwargs)

    def query_property(self, query_cls=None):
        """return a class property which produces a `Query` object
        against the class when called.

        e.g.::

            Session = scoped_session(sessionmaker())

            class MyClass(object):
                query = Session.query_property()

            # after mappers are defined
            result = MyClass.query.filter(MyClass.name=='foo').all()

        Produces instances of the session's configured query class by
        default.  To override and use a custom implementation, provide
        a ``query_cls`` callable.  The callable will be invoked with
        the class's mapper as a positional argument and a session
        keyword argument.

        There is no limit to the number of query properties placed on
        a class.

        """
        class query(object):
            def __get__(s, instance, owner):
                try:
                    mapper = class_mapper(owner)
                    if mapper:
                        if query_cls:
                            # custom query class
                            return query_cls(mapper, session=self.registry())
                        else:
                            # session's configured query class
                            return self.registry().query(mapper)
                except orm_exc.UnmappedClassError:
                    return None

        return query()
예제 #6
0
파일: scoping.py 프로젝트: MaxMorais/skink
class ScopedSession(object):
    """Provides thread-local management of Sessions.

    Usage::

      Session = scoped_session(sessionmaker(autoflush=True))

      ... use session normally.

    """

    def __init__(self, session_factory, scopefunc=None):
        self.session_factory = session_factory
        if scopefunc:
            self.registry = ScopedRegistry(session_factory, scopefunc)
        else:
            self.registry = ThreadLocalRegistry(session_factory)
        self.extension = _ScopedExt(self)

    def __call__(self, **kwargs):
        if kwargs:
            scope = kwargs.pop('scope', False)
            if scope is not None:
                if self.registry.has():
                    raise sa_exc.InvalidRequestError("Scoped session is already present; no new arguments may be specified.")
                else:
                    sess = self.session_factory(**kwargs)
                    self.registry.set(sess)
                    return sess
            else:
                return self.session_factory(**kwargs)
        else:
            return self.registry()

    def remove(self):
        if self.registry.has():
            self.registry().close()
        self.registry.clear()

    @deprecated("Session.mapper is deprecated.  "
        "Please see http://www.sqlalchemy.org/trac/wiki/UsageRecipes/SessionAwareMapper "
        "for information on how to replicate its behavior.")
    def mapper(self, *args, **kwargs):
        """return a mapper() function which associates this ScopedSession with the Mapper.
        
        DEPRECATED.
        
        """

        from sqlalchemy.orm import mapper

        extension_args = dict((arg, kwargs.pop(arg))
                              for arg in get_cls_kwargs(_ScopedExt)
                              if arg in kwargs)

        kwargs['extension'] = extension = to_list(kwargs.get('extension', []))
        if extension_args:
            extension.append(self.extension.configure(**extension_args))
        else:
            extension.append(self.extension)
        return mapper(*args, **kwargs)

    def configure(self, **kwargs):
        """reconfigure the sessionmaker used by this ScopedSession."""

        self.session_factory.configure(**kwargs)

    def query_property(self, query_cls=None):
        """return a class property which produces a `Query` object against the
        class when called.

        e.g.::
            Session = scoped_session(sessionmaker())

            class MyClass(object):
                query = Session.query_property()

            # after mappers are defined
            result = MyClass.query.filter(MyClass.name=='foo').all()

        Produces instances of the session's configured query class by
        default.  To override and use a custom implementation, provide
        a ``query_cls`` callable.  The callable will be invoked with
        the class's mapper as a positional argument and a session
        keyword argument.

        There is no limit to the number of query properties placed on
        a class.

        """
        class query(object):
            def __get__(s, instance, owner):
                try:
                    mapper = class_mapper(owner)
                    if mapper:
                        if query_cls:
                            # custom query class
                            return query_cls(mapper, session=self.registry())
                        else:
                            # session's configured query class
                            return self.registry().query(mapper)
                except orm_exc.UnmappedClassError:
                    return None
        return query()
예제 #7
0
class ScopedSession(object):
    """Provides thread-local management of Sessions.

    Usage::

      Session = scoped_session(sessionmaker())

    ... use Session normally.

    The internal registry is accessible as well,
    and by default is an instance of :class:`.ThreadLocalRegistry`.


    """

    def __init__(self, session_factory, scopefunc=None):
        self.session_factory = session_factory
        if scopefunc:
            self.registry = ScopedRegistry(session_factory, scopefunc)
        else:
            self.registry = ThreadLocalRegistry(session_factory)

    def __call__(self, **kwargs):
        if kwargs:
            scope = kwargs.pop("scope", False)
            if scope is not None:
                if self.registry.has():
                    raise sa_exc.InvalidRequestError(
                        "Scoped session is already present; " "no new arguments may be specified."
                    )
                else:
                    sess = self.session_factory(**kwargs)
                    self.registry.set(sess)
                    return sess
            else:
                return self.session_factory(**kwargs)
        else:
            return self.registry()

    def remove(self):
        """Dispose of the current contextual session."""

        if self.registry.has():
            self.registry().close()
        self.registry.clear()

    def configure(self, **kwargs):
        """reconfigure the sessionmaker used by this ScopedSession."""

        if self.registry.has():
            warn(
                "At least one scoped session is already present. "
                " configure() can not affect sessions that have "
                "already been created."
            )

        self.session_factory.configure(**kwargs)

    def query_property(self, query_cls=None):
        """return a class property which produces a `Query` object against the
        class when called.

        e.g.::

            Session = scoped_session(sessionmaker())

            class MyClass(object):
                query = Session.query_property()

            # after mappers are defined
            result = MyClass.query.filter(MyClass.name=='foo').all()

        Produces instances of the session's configured query class by
        default.  To override and use a custom implementation, provide
        a ``query_cls`` callable.  The callable will be invoked with
        the class's mapper as a positional argument and a session
        keyword argument.

        There is no limit to the number of query properties placed on
        a class.

        """

        class query(object):
            def __get__(s, instance, owner):
                try:
                    mapper = class_mapper(owner)
                    if mapper:
                        if query_cls:
                            # custom query class
                            return query_cls(mapper, session=self.registry())
                        else:
                            # session's configured query class
                            return self.registry().query(mapper)
                except orm_exc.UnmappedClassError:
                    return None

        return query()
예제 #8
0
class scoped_session(object):
    """Provides scoped management of :class:`.Session` objects.

    See :ref:`unitofwork_contextual` for a tutorial.

    """

    session_factory = None
    """The `session_factory` provided to `__init__` is stored in this
    attribute and may be accessed at a later time.  This can be useful when
    a new non-scoped :class:`.Session` or :class:`.Connection` to the
    database is needed."""
    def __init__(self, session_factory, scopefunc=None):
        """Construct a new :class:`.scoped_session`.

        :param session_factory: a factory to create new :class:`.Session`
         instances. This is usually, but not necessarily, an instance
         of :class:`.sessionmaker`.
        :param scopefunc: optional function which defines
         the current scope.   If not passed, the :class:`.scoped_session`
         object assumes "thread-local" scope, and will use
         a Python ``threading.local()`` in order to maintain the current
         :class:`.Session`.  If passed, the function should return
         a hashable token; this token will be used as the key in a
         dictionary in order to store and retrieve the current
         :class:`.Session`.

        """
        self.session_factory = session_factory

        if scopefunc:
            self.registry = ScopedRegistry(session_factory, scopefunc)
        else:
            self.registry = ThreadLocalRegistry(session_factory)

    def __call__(self, **kw):
        r"""Return the current :class:`.Session`, creating it
        using the :attr:`.scoped_session.session_factory` if not present.

        :param \**kw: Keyword arguments will be passed to the
         :attr:`.scoped_session.session_factory` callable, if an existing
         :class:`.Session` is not present.  If the :class:`.Session` is present
         and keyword arguments have been passed,
         :exc:`~sqlalchemy.exc.InvalidRequestError` is raised.

        """
        if kw:
            if self.registry.has():
                raise sa_exc.InvalidRequestError(
                    "Scoped session is already present; "
                    "no new arguments may be specified.")
            else:
                sess = self.session_factory(**kw)
                self.registry.set(sess)
                return sess
        else:
            return self.registry()

    def remove(self):
        """Dispose of the current :class:`.Session`, if present.

        This will first call :meth:`.Session.close` method
        on the current :class:`.Session`, which releases any existing
        transactional/connection resources still being held; transactions
        specifically are rolled back.  The :class:`.Session` is then
        discarded.   Upon next usage within the same scope,
        the :class:`.scoped_session` will produce a new
        :class:`.Session` object.

        """

        if self.registry.has():
            self.registry().close()
        self.registry.clear()

    def configure(self, **kwargs):
        """reconfigure the :class:`.sessionmaker` used by this
        :class:`.scoped_session`.

        See :meth:`.sessionmaker.configure`.

        """

        if self.registry.has():
            self._logger.warning(
                "At least one scoped session is already present. "
                " configure() can not affect sessions that have "
                "already been created.")

        self.session_factory.configure(**kwargs)
예제 #9
0
파일: db.py 프로젝트: alecthomas/waffle
 def __init__(self, session_factory):
     self._session_factory = session_factory
     self._registry = ThreadLocalRegistry(session_factory)
예제 #10
0
파일: db.py 프로젝트: alecthomas/waffle
class ExplicitSessionManager(object):
    """A thread-safe explicit session manager.

    This provides the following semantics:

    - Sessions are started via a contextmanager.
    - Using the ExplicitSessionManager (typically via Model.query) is invalid.
    - Entering a Session context opens a transaction and returns a session recursively.
    - Provides a query_property that can only be used within a transaction.
    - A transaction can *only* be opened by a context manager.
    """

    def __init__(self, session_factory):
        self._session_factory = session_factory
        self._registry = ThreadLocalRegistry(session_factory)

    def configure(self, **config):
        self._session_factory.configure(**config)

    def __enter__(self):
        if not self._registry.has():
            sess = self._session_factory()
            self._registry.set(sess)
        else:
            sess = self._registry()
        return sess.__enter__()

    def begin(self):
        return self.__enter__()

    def __exit__(self, type, value, traceback):
        if self._registry.has():
            sess = self._registry()
            sess.__exit__(type, value, traceback)

    def remove(self):
        """Close the associated session and disconnect."""
        if self._registry.has():
            self._registry().close()
        self._registry.clear()

    def query_property(self, query_cls=None):
        class query(object):
            def __get__(s, instance, owner):
                try:
                    mapper = class_mapper(owner)
                    if mapper:
                        if not self._registry.has() or not self._registry()._depth:
                            raise InvalidRequestError('Cannot access %s.query outside transaction, use with session: ...' % owner.__name__)
                        if query_cls:
                            # custom query class
                            return query_cls(mapper, session=self._registry())
                        else:
                            # session's configured query class
                            return self._registry().query(mapper)
                except UnmappedClassError:
                    return None
        return query()

    def __getattr__(self, name):
        """Proxy all attribute access to current session."""
        if not self._registry.has():
            raise InvalidRequestError('No transaction is active, use "with session: ..."')
        return getattr(self._registry(), name)
예제 #11
0
class ScopedSession(object):
    """Provides thread-local management of Sessions.

    Usage::

      Session = scoped_session(sessionmaker(autoflush=True))

      ... use session normally.

    """
    def __init__(self, session_factory, scopefunc=None):
        self.session_factory = session_factory
        if scopefunc:
            self.registry = ScopedRegistry(session_factory, scopefunc)
        else:
            self.registry = ThreadLocalRegistry(session_factory)
        self.extension = _ScopedExt(self)

    def __call__(self, **kwargs):
        if kwargs:
            scope = kwargs.pop('scope', False)
            if scope is not None:
                if self.registry.has():
                    raise sa_exc.InvalidRequestError(
                        "Scoped session is already present; no new arguments may be specified."
                    )
                else:
                    sess = self.session_factory(**kwargs)
                    self.registry.set(sess)
                    return sess
            else:
                return self.session_factory(**kwargs)
        else:
            return self.registry()

    def remove(self):
        """Dispose of the current contextual session."""

        if self.registry.has():
            self.registry().close()
        self.registry.clear()

    @deprecated(
        "Session.mapper is deprecated.  "
        "Please see http://www.sqlalchemy.org/trac/wiki/UsageRecipes/SessionAwareMapper "
        "for information on how to replicate its behavior.")
    def mapper(self, *args, **kwargs):
        """return a mapper() function which associates this ScopedSession with the Mapper.

        DEPRECATED.

        """

        from sqlalchemy.orm import mapper

        extension_args = dict((arg, kwargs.pop(arg))
                              for arg in get_cls_kwargs(_ScopedExt)
                              if arg in kwargs)

        kwargs['extension'] = extension = to_list(kwargs.get('extension', []))
        if extension_args:
            extension.append(self.extension.configure(**extension_args))
        else:
            extension.append(self.extension)
        return mapper(*args, **kwargs)

    def configure(self, **kwargs):
        """reconfigure the sessionmaker used by this ScopedSession."""

        self.session_factory.configure(**kwargs)

    def query_property(self, query_cls=None):
        """return a class property which produces a `Query` object against the
        class when called.

        e.g.::
            Session = scoped_session(sessionmaker())

            class MyClass(object):
                query = Session.query_property()

            # after mappers are defined
            result = MyClass.query.filter(MyClass.name=='foo').all()

        Produces instances of the session's configured query class by
        default.  To override and use a custom implementation, provide
        a ``query_cls`` callable.  The callable will be invoked with
        the class's mapper as a positional argument and a session
        keyword argument.

        There is no limit to the number of query properties placed on
        a class.

        """
        class query(object):
            def __get__(s, instance, owner):
                try:
                    mapper = class_mapper(owner)
                    if mapper:
                        if query_cls:
                            # custom query class
                            return query_cls(mapper, session=self.registry())
                        else:
                            # session's configured query class
                            return self.registry().query(mapper)
                except orm_exc.UnmappedClassError:
                    return None

        return query()
예제 #12
0
파일: db.py 프로젝트: alecthomas/waffle
 def __init__(self, session_factory):
     self._session_factory = session_factory
     self._registry = ThreadLocalRegistry(session_factory)
예제 #13
0
파일: db.py 프로젝트: alecthomas/waffle
class ExplicitSessionManager(object):
    """A thread-safe explicit session manager.

    This provides the following semantics:

    - Sessions are started via a contextmanager.
    - Using the ExplicitSessionManager (typically via Model.query) is invalid.
    - Entering a Session context opens a transaction and returns a session recursively.
    - Provides a query_property that can only be used within a transaction.
    - A transaction can *only* be opened by a context manager.
    """
    def __init__(self, session_factory):
        self._session_factory = session_factory
        self._registry = ThreadLocalRegistry(session_factory)

    def configure(self, **config):
        self._session_factory.configure(**config)

    def __enter__(self):
        if not self._registry.has():
            sess = self._session_factory()
            self._registry.set(sess)
        else:
            sess = self._registry()
        return sess.__enter__()

    def begin(self):
        return self.__enter__()

    def __exit__(self, type, value, traceback):
        if self._registry.has():
            sess = self._registry()
            sess.__exit__(type, value, traceback)

    def remove(self):
        """Close the associated session and disconnect."""
        if self._registry.has():
            self._registry().close()
        self._registry.clear()

    def query_property(self, query_cls=None):
        class query(object):
            def __get__(s, instance, owner):
                try:
                    mapper = class_mapper(owner)
                    if mapper:
                        if not self._registry.has() or not self._registry(
                        )._depth:
                            raise InvalidRequestError(
                                'Cannot access %s.query outside transaction, use with session: ...'
                                % owner.__name__)
                        if query_cls:
                            # custom query class
                            return query_cls(mapper, session=self._registry())
                        else:
                            # session's configured query class
                            return self._registry().query(mapper)
                except UnmappedClassError:
                    return None

        return query()

    def __getattr__(self, name):
        """Proxy all attribute access to current session."""
        if not self._registry.has():
            raise InvalidRequestError(
                'No transaction is active, use "with session: ..."')
        return getattr(self._registry(), name)