From 0a8400ecb253e3484cb4a703daf33b644f29fe1d Mon Sep 17 00:00:00 2001 From: "russell@unturf.com" Date: Tue, 7 Apr 2026 12:53:55 -0400 Subject: [PATCH] fix: wrap script DB sessions in transaction.manager to resolve NoTransaction error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit digest_sender cron was crashing with transaction.interfaces.NoTransaction. bootstrap() doesn't start a transaction — pyramid_tm handles that for web requests but not console scripts. Wrap DB work in transaction.manager context instead of manual transaction.commit() calls. Same latent defect fixed in backfill_karaoke.py. --- make_post_sell/lib/digest_sender.py | 16 +++++++--------- make_post_sell/scripts/backfill_karaoke.py | 8 +++----- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/make_post_sell/lib/digest_sender.py b/make_post_sell/lib/digest_sender.py index 8cb5c80..ab26209 100644 --- a/make_post_sell/lib/digest_sender.py +++ b/make_post_sell/lib/digest_sender.py @@ -15,6 +15,7 @@ Cron setup: import argparse import sys import logging +import transaction from pyramid.paster import bootstrap, setup_logging @@ -185,24 +186,21 @@ def run(env, frequency_str, dry_run=False): # Update last_digest_timestamp sub.last_digest_timestamp = now_timestamp() - import transaction - transaction.commit() - def main(argv=sys.argv): args = parse_args(argv) setup_logging(args.config_uri) - env = bootstrap(args.config_uri) logger.info( f"Digest sender started: frequency={args.frequency}, dry_run={args.dry_run}" ) - try: - run(env, args.frequency, args.dry_run) - finally: - logger.info("Digest sender finished") - env["closer"]() + with bootstrap(args.config_uri) as env: + try: + with transaction.manager: + run(env, args.frequency, args.dry_run) + finally: + logger.info("Digest sender finished") if __name__ == "__main__": diff --git a/make_post_sell/scripts/backfill_karaoke.py b/make_post_sell/scripts/backfill_karaoke.py index abcbf12..72c26c5 100644 --- a/make_post_sell/scripts/backfill_karaoke.py +++ b/make_post_sell/scripts/backfill_karaoke.py @@ -8,6 +8,7 @@ Usage: import argparse import sys +import transaction from pyramid.paster import bootstrap @@ -77,10 +78,6 @@ def backfill(env, dry_run=True): print(f" FAILED") errors += 1 - if not dry_run: - import transaction - transaction.commit() - print("-" * 50) print(f"Processed: {processed} Skipped: {skipped} Errors: {errors} Dry run: {dry_run}") @@ -98,7 +95,8 @@ def main(): with bootstrap(args.config_uri) as env: try: - backfill(env, dry_run=not args.execute) + with transaction.manager: + backfill(env, dry_run=not args.execute) except KeyboardInterrupt: print("\nCancelled") sys.exit(1)