class ScopedSession(object): """Provides thread-local management of Sessions. Usage:: Session = scoped_session(sessionmaker(autoflush=True)) To map classes so that new instances are saved in the current Session automatically, as well as to provide session-aware class attributes such as "query": mapper = Session.mapper mapper(Class, table, ...) """ def __init__(self, session_factory, scopefunc=None): self.session_factory = session_factory self.registry = ScopedRegistry(session_factory, scopefunc) 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 exceptions.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() def mapper(self, *args, **kwargs): """return a mapper() function which associates this ScopedSession with the Mapper.""" 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): """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() """ class query(object): def __get__(s, instance, owner): mapper = class_mapper(owner, raiseerror=False) if mapper: return self.registry().query(mapper) else: return None return query()
class ScopedSession(object): """Provides thread-local management of Sessions. Usage:: Session = scoped_session(sessionmaker(autoflush=True)) To map classes so that new instances are saved in the current Session automatically, as well as to provide session-aware class attributes such as "query": mapper = Session.mapper mapper(Class, table, ...) """ def __init__(self, session_factory, scopefunc=None): self.session_factory = session_factory self.registry = ScopedRegistry(session_factory, scopefunc) 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 exceptions.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() def mapper(self, *args, **kwargs): """return a mapper() function which associates this ScopedSession with the Mapper.""" 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): """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() """ class query(object): def __get__(s, instance, owner): mapper = class_mapper(owner, raiseerror=False) if mapper: return self.registry().query(mapper) else: return None return query()
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 self.registry = ScopedRegistry(session_factory, scopefunc) 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()