Files
shopdb-flask/scripts/site_imports/winc/batches.py
benjamin.baker 17825ec8f1 Add WINC batches CLI and a CLI how-to README
The web import panel can list applied/undone batches, but the CLI had no equivalent, so an operator working from the shell had no way to find a batchid to feed into the undo command. Add a read-only batches command that reuses the same importbatches query, and a short README documenting the four WINC commands and their switches.
2026-09-03 08:07:01 -04:00

92 lines
2.9 KiB
Python

"""WINC machine adoption - BATCHES (list applied/undone import batches).
A read-only companion to writer.py and undo.py: it prints the WINC batches
newest-first so an operator can find a batchid to feed `--batch` into the undo
CLI. Like the other WINC commands it is WINC-named only for discoverability; the
underlying importbatches table is import-agnostic, so this simply filters to the
winc-machine-adoption kind.
"""
import argparse
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(
os.path.dirname(os.path.abspath(__file__))))))
from dotenv import load_dotenv
from pathlib import Path
load_dotenv(Path(__file__).resolve().parents[3] / '.env')
from sqlalchemy import text
from scripts.site_imports.winc.dry_run import build_app_connection
_KIND = 'winc-machine-adoption'
def _iso(value):
# PyMySQL hands back datetime objects; SQLite hands back the stored ISO
# string. Normalise both to an ISO string so the output is stable.
if value is None:
return '-'
if hasattr(value, 'isoformat'):
return value.isoformat()
return str(value)
def list_batches(connection, limit):
rows = connection.execute(text(
'SELECT batchid, kind, rowcount, createdat, createdby, status, '
'undoneat FROM importbatches WHERE kind = :kind '
'ORDER BY createdat DESC LIMIT :limit'),
{'kind': _KIND, 'limit': limit}).fetchall()
return [
{'batchid': r[0], 'kind': r[1], 'rowcount': r[2],
'createdat': _iso(r[3]), 'createdby': r[4], 'status': r[5],
'undoneat': _iso(r[6])}
for r in rows
]
def _print_table(batches):
if not batches:
print('No WINC import batches found.')
return
header = '%-36s %-8s %5s %-20s %-16s %s' % (
'batchid', 'status', 'rows', 'createdat', 'createdby', 'undoneat')
print(header)
print('-' * len(header))
for batch in batches:
print('%-36s %-8s %5s %-20s %-16s %s' % (
batch['batchid'], batch['status'], batch['rowcount'],
batch['createdat'], batch['createdby'] or '-', batch['undoneat']))
def main(argv=None):
parser = argparse.ArgumentParser(
description='List applied/undone WINC import batches, newest first.')
parser.add_argument('--limit', type=int, default=50,
help='Maximum number of batches to show (default 50).')
parser.add_argument('--json', action='store_true',
help='Emit the batches as JSON instead of a table.')
args = parser.parse_args(argv)
if args.limit < 1:
parser.error('--limit must be a positive integer')
_app, connection = build_app_connection()
batches = list_batches(connection, args.limit)
if args.json:
import json
print(json.dumps(batches, indent=2))
else:
_print_table(batches)
return 0
if __name__ == '__main__':
sys.exit(main())