Coverage for .tox/coverage/lib/python3.11/site-packages/wuttjamaican/db/sess.py: 100%
25 statements
« prev ^ index » next coverage.py v7.3.2, created at 2024-08-15 16:21 -0500
« prev ^ index » next coverage.py v7.3.2, created at 2024-08-15 16:21 -0500
1# -*- coding: utf-8; -*-
2################################################################################
3#
4# WuttJamaican -- Base package for Wutta Framework
5# Copyright © 2023 Lance Edgar
6#
7# This file is part of Wutta Framework.
8#
9# Wutta Framework is free software: you can redistribute it and/or modify it
10# under the terms of the GNU General Public License as published by the Free
11# Software Foundation, either version 3 of the License, or (at your option) any
12# later version.
13#
14# Wutta Framework is distributed in the hope that it will be useful, but
15# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17# more details.
18#
19# You should have received a copy of the GNU General Public License along with
20# Wutta Framework. If not, see <http://www.gnu.org/licenses/>.
21#
22################################################################################
23"""
24WuttJamaican - database sessions
26.. class:: Session
28 SQLAlchemy session class used for all (normal) :term:`app database`
29 connections.
31 See the upstream :class:`sqlalchemy:sqlalchemy.orm.Session` docs
32 for more info.
33"""
35from sqlalchemy import orm
38Session = orm.sessionmaker()
41class short_session:
42 """
43 Context manager for a short-lived database session.
45 A canonical use case for this is when the config object needs to
46 grab a single setting value from the DB, but it does not have an
47 active DB session to do it. This context manager is used to
48 produce the session, and close it when finished. For example::
50 with short_session(config) as s:
51 result = s.query("select something from somewhere").scalar()
53 How it goes about producing the session instance will depend on
54 which of the following 3 params are given (explained below):
56 * ``config``
57 * ``factory``
58 * ``session``
60 Note that it is also okay if you provide *none* of the above
61 params, in which case the main :class:`Session` class will be used
62 as the factory.
64 :param config: Optional app config object. If a new session must
65 be created, the config will be consulted to determine the
66 factory which is used to create the new session.
68 :param factory: Optional factory to use when making a new session.
69 If specified, this will override the ``config`` mechanism.
71 :param session: Optional SQLAlchemy session instance. If a valid
72 session is provided here, it will be used instead of creating a
73 new/temporary session.
75 :param commit: Whether the temporary session should be committed
76 before it is closed. This flag has no effect if a valid
77 ``session`` instance is provided, since no temporary session
78 will be created.
79 """
81 def __init__(self, config=None, factory=None, session=None, commit=False):
82 self.config = config
83 self.factory = factory
84 self.session = session
85 self.private = not bool(session)
86 self.commit = commit
88 def __enter__(self):
89 if not self.session:
90 if not self.factory:
91 if self.config:
92 app = self.config.get_app()
93 self.factory = app.make_session
94 else:
95 self.factory = Session
96 self.session = self.factory()
97 return self.session
99 def __exit__(self, exc_type, exc_value, traceback):
100 if self.private:
101 if self.commit:
102 self.session.commit()
103 self.session.close()
104 self.session = None