From 56871dc906e1b558988a4bddd402146d5a82a8ba Mon Sep 17 00:00:00 2001 From: yumoqing Date: Sun, 24 May 2026 22:02:52 +0800 Subject: [PATCH] =?UTF-8?q?fix(llmage):=20=E4=BF=AE=E5=A4=8Dbackup=5Faccou?= =?UTF-8?q?nted=5Fllmusage=E4=B8=ADsor.execute()=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E5=80=BC=E8=AF=AF=E7=94=A8=EF=BC=88MySQL=20cursor.execute?= =?UTF-8?q?=E8=BF=94=E5=9B=9ENone=E9=9D=9Erowcount=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- llmage/accounting.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/llmage/accounting.py b/llmage/accounting.py index 53b11c9..c34d42b 100644 --- a/llmage/accounting.py +++ b/llmage/accounting.py @@ -240,28 +240,36 @@ async def llm_accoung_failed(luid, reason=None): async def backup_accounted_llmusage(cutoff_date): - """Backup accounted records with use_date < cutoff_date to history table using single SQL statements.""" + """Backup accounted records with use_date < cutoff_date to history table.""" env = ServerEnv() ts = env.timestampstr() async with get_sor_context(env, 'llmage') as sor: + # Step 0: Count records to backup + count_sql = """SELECT COUNT(*) as cnt FROM llmusage +WHERE accounting_status='accounted' AND use_date < ${cutoff_date}$""" + count_recs = await sor.sqlExe(count_sql, {'cutoff_date': cutoff_date}) + total = count_recs[0].cnt if count_recs else 0 + if total == 0: + debug(f'backup_accounted_llmusage: no records to backup for use_date < {cutoff_date}') + return 0 + debug(f'backup_accounted_llmusage: {total} records to backup') + # Step 1: INSERT INTO history SELECT from main table insert_sql = """INSERT INTO llmusage_history (id, llmid, use_date, use_time, userid, usages, ioinfo, transno, responsed_seconds, finish_seconds, status, taskid, amount, cost, userorgid, ownerid, accounting_status, backup_time) SELECT id, llmid, use_date, use_time, userid, usages, ioinfo, transno, responsed_seconds, finish_seconds, status, taskid, amount, cost, userorgid, ownerid, accounting_status, ${ts}$ FROM llmusage WHERE accounting_status='accounted' AND use_date < ${cutoff_date}$""" - result = await sor.execute(insert_sql, {'cutoff_date': cutoff_date, 'ts': ts}) - inserted = result if isinstance(result, int) else 0 - debug(f'backup_accounted_llmusage: {inserted} records inserted to history') + await sor.execute(insert_sql, {'cutoff_date': cutoff_date, 'ts': ts}) + debug(f'backup_accounted_llmusage: inserted {total} records to history') - if inserted > 0: - # Step 2: DELETE from main table - delete_sql = """DELETE FROM llmusage + # Step 2: DELETE from main table + delete_sql = """DELETE FROM llmusage WHERE accounting_status='accounted' AND use_date < ${cutoff_date}$""" - await sor.execute(delete_sql, {'cutoff_date': cutoff_date}) - debug(f'backup_accounted_llmusage: {inserted} records deleted from main table') + await sor.execute(delete_sql, {'cutoff_date': cutoff_date}) + debug(f'backup_accounted_llmusage: deleted {total} records from main table') - return inserted + return total async def get_failed_accounting_records(filters=None, page=1, page_size=50):