async def test_finish_commit(raise_exception, tmp_path): """ Tests that the session is automatically committed if and only if the context was not exited with an exception. """ db_path = tmp_path / "test.db" engine = create_engine(f"sqlite:///{db_path}", poolclass=NullPool) with engine.begin() as connection: connection.execute(text("CREATE TABLE foo (id INTEGER PRIMARY KEY)")) component = SQLAlchemyComponent(url={ "drivername": "sqlite", "database": str(db_path) }, ) with ExitStack() as stack: async with Context() as ctx: await component.start(ctx) session = ctx.require_resource(Session) session.execute(text("INSERT INTO foo (id) VALUES(3)")) if raise_exception: stack.enter_context(pytest.raises(Exception, match="dummy")) raise Exception("dummy") rows = connection.execute(text("SELECT * FROM foo")).fetchall() assert len(rows) == (0 if raise_exception else 1)
def sqlite_memory_engine(): engine = create_engine( "sqlite:///:memory:", connect_args=dict(check_same_thread=False) ) apply_sqlite_hacks(engine) yield engine engine.dispose()
def sqlite_file_engine(tmp_path_factory): db_path = tmp_path_factory.mktemp("asphalt-sqlalchemy") / "test.db" engine = create_engine( f"sqlite:///{db_path}", connect_args=dict(check_same_thread=False) ) apply_sqlite_hacks(engine) yield engine engine.dispose() if db_path.exists(): db_path.unlink()
async def test_bind_sync(): """Test that a Connection can be passed as "bind" in place of "url".""" engine = create_engine("sqlite:///:memory:") connection = engine.connect() component = SQLAlchemyComponent(bind=connection) async with Context() as ctx: await component.start(ctx) assert ctx.require_resource(Engine) is engine assert ctx.require_resource(Session).bind is connection connection.close()
async def test_session_event_async(request, asyncpg_url, psycopg2_url): """Test that creating a session in a context does not leak memory.""" listener_session: Session listener_thread: Thread def listener(session: Session) -> None: nonlocal listener_session, listener_thread try: async_session = get_resource(AsyncSession) except NoCurrentContext: return if async_session and session is async_session.sync_session: listener_session = session listener_thread = current_thread() listen(Session, "before_commit", listener) request.addfinalizer(lambda: remove(Session, "before_commit", listener)) component = SQLAlchemyComponent(url=asyncpg_url) async with Context() as ctx: await component.start(ctx) dbsession = ctx.require_resource(AsyncSession) await dbsession.run_sync( lambda session: Person.metadata.create_all(session.bind)) dbsession.add(Person(name="Test person")) assert listener_session is dbsession.sync_session assert listener_thread is current_thread() engine = create_engine(psycopg2_url) with Session(engine) as sess: sess.add(Person(name="Test person 2")) sess.commit() engine.dispose() assert listener_session is dbsession.sync_session assert listener_thread is current_thread()
def testing_engine(url=None, options=None, future=False): """Produce an engine configured by --options with optional overrides.""" if future or config.db and config.db._is_future: from sqlalchemy.future import create_engine else: from sqlalchemy import create_engine from sqlalchemy.engine.url import make_url if not options: use_reaper = True else: use_reaper = options.pop("use_reaper", True) url = url or config.db.url url = make_url(url) if options is None: if config.db is None or url.drivername == config.db.url.drivername: options = config.db_opts else: options = {} elif config.db is not None and url.drivername == config.db.url.drivername: default_opt = config.db_opts.copy() default_opt.update(options) engine = create_engine(url, **options) engine._has_events = True # enable event blocks, helps with profiling if isinstance(engine.pool, pool.QueuePool): engine.pool._timeout = 0 engine.pool._max_overflow = 0 if use_reaper: testing_reaper.add_engine(engine) return engine
def __init__(self): super().__init__() self.engine = create_engine(self.get_connection_url(), future=True) self.sessionmaker = sessionmaker(self.engine)
def psycopg2_engine(patch_psycopg2, psycopg2_url): engine = create_engine(psycopg2_url) yield engine engine.dispose()
def pymysql_engine(mysql_url): engine = create_engine(mysql_url) yield engine engine.dispose()
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with JulianBC. If not, see <https://www.gnu.org/licenses/>. from src.customdatetime import ( ConvertibleDate, ConvertibleDateTime, ConvertibleTime, ) from sqlalchemy.future import create_engine from sqlalchemy.orm import scoped_session, sessionmaker from src.db import ConvertibleCalendar, ConvertibleClock from src.db.utils import Base engine = create_engine("sqlite://", future=True) Session = scoped_session(sessionmaker(bind=engine)) session = Session() Base.metadata.create_all(engine) session.commit() gregorian = ConvertibleCalendar( name="Gregorian", weekday_names=( "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", ),