# Create your tasks here from __future__ import absolute_import, unicode_literals from datetime import timedelta from apps.monitor.models import DrfRequestLog from apps.utils.tasks import CustomTask from celery import shared_task from django.utils import timezone from django.conf import settings import os from apps.utils.sql import execute_raw_sql @shared_task(base=CustomTask) def clear_drf_log(days: int = 7): """清除N天前的日志记录,默认七天 清除N天前的日志记录 """ now = timezone.now() days7_ago = now - timedelta(days=days) DrfRequestLog.objects.filter(create_time__lte=days7_ago).delete() @shared_task(base=CustomTask) def clear_dbbackup(num: int=7): """ 清除N条前的数据库备份记录,默认七条 清除N条前的数据库备份记录 """ from apps.monitor.views import get_file_list backpath = settings.BACKUP_PATH + '/database' files = get_file_list(backpath) files_remove_list = files[num:] for f in files_remove_list: filepath = os.path.join(backpath, f) os.remove(filepath) @shared_task(base=CustomTask) def clean_timescaledb_job_his(num: int = 30): execute_raw_sql(f""" DO $$ DECLARE batch_size INTEGER := 100000; -- 每次删除的行数 deleted_count INTEGER := 0; BEGIN IF EXISTS ( SELECT 1 FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = '_timescaledb_internal' AND c.relname = 'bgw_job_stat_history' ) THEN RAISE NOTICE 'Start cleaning _timescaledb_internal.bgw_job_stat_history ...'; LOOP WITH del AS ( SELECT ctid FROM _timescaledb_internal.bgw_job_stat_history WHERE execution_start < NOW() - INTERVAL '{num} days' LIMIT batch_size ) DELETE FROM _timescaledb_internal.bgw_job_stat_history WHERE ctid IN (SELECT ctid FROM del); GET DIAGNOSTICS deleted_count = ROW_COUNT; RAISE NOTICE 'Deleted % rows...', deleted_count; EXIT WHEN deleted_count = 0; PERFORM pg_sleep(0.1); -- 稍微休息,避免压力过大 END LOOP; RAISE NOTICE '✅ Data cleanup complete. Run VACUUM FULL manually.'; ELSE RAISE NOTICE 'Table _timescaledb_internal.bgw_job_stat_history not found.'; END IF; END$$; """, timeout=None)