Files
aiData/Tools/T5_ClearHistory.py

140 lines
5.0 KiB
Python
Raw Normal View History

2026-01-15 07:29:51 +08:00
import asyncio
import os
import sys
import logging
2026-01-15 07:42:27 +08:00
from typing import List, Dict
2026-01-15 07:29:51 +08:00
2026-01-15 07:40:53 +08:00
# 确保项目根目录在 sys.path 中,并且优先于外部同名模块
2026-01-15 07:42:27 +08:00
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
2026-01-15 07:29:51 +08:00
if project_root not in sys.path:
2026-01-15 07:40:53 +08:00
sys.path.insert(0, project_root)
from Util import Win32Patch
2026-01-15 07:29:51 +08:00
from DbKit.Db import Db
from Util.RedisKit import RedisKit
from sqlalchemy.sql import text
2026-01-15 07:42:27 +08:00
2026-01-15 07:40:53 +08:00
try:
from Config.Config import DB_URL
except ModuleNotFoundError:
import importlib.util
2026-01-15 07:42:27 +08:00
_root_dir_cfg = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
2026-01-15 07:40:53 +08:00
_config_path_cfg = os.path.join(_root_dir_cfg, "Config", "Config.py")
_spec_cfg = importlib.util.spec_from_file_location("project_config_fallback", _config_path_cfg)
_cfg_mod = importlib.util.module_from_spec(_spec_cfg)
assert _spec_cfg.loader is not None
_spec_cfg.loader.exec_module(_cfg_mod)
DB_URL = _cfg_mod.DB_URL
2026-01-15 07:29:51 +08:00
# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
2026-01-15 07:42:27 +08:00
logger = logging.getLogger("T5_ClearHistory")
2026-01-15 07:29:51 +08:00
2026-01-15 07:42:27 +08:00
# 供应商配置映射
VENDORS = {
"1": {"name": "特来电", "redis_pattern": "crawled:tld:*"},
"2": {"name": "新电途", "redis_pattern": "crawled:xdt:*"},
"3": {"name": "艾特吉易充", "redis_pattern": "crawled:aite:*"},
"4": {"name": "驿来特", "redis_pattern": "crawled:ylt:*"},
}
async def clear_vendor_data(db: Db, redis_kit: RedisKit, vendor_info: Dict):
2026-01-15 07:29:51 +08:00
"""
2026-01-15 07:42:27 +08:00
清理特定供应商的数据库和 Redis 数据
2026-01-15 07:29:51 +08:00
"""
2026-01-15 07:42:27 +08:00
operator = vendor_info["name"]
pattern = vendor_info["redis_pattern"]
2026-01-15 07:29:51 +08:00
2026-01-15 07:42:27 +08:00
logger.info(f"--- 正在清理供应商: {operator} ---")
2026-01-15 07:29:51 +08:00
2026-01-15 07:42:27 +08:00
# 1. 数据库清理
2026-01-15 07:29:51 +08:00
try:
async with db.AsyncSessionLocal() as session:
async with session.begin():
# 先删除从表记录(通过 station_hash 关联)
# 1. t_station_status_scd
sql_status = """
DELETE FROM t_station_status_scd
WHERE station_hash IN (
SELECT station_hash FROM t_station_profile_scd WHERE operator = :operator
)
"""
result_status = await session.execute(text(sql_status), {"operator": operator})
2026-01-15 07:42:27 +08:00
logger.info(f"[{operator}] t_station_status_scd 已删除 {result_status.rowcount} 行。")
2026-01-15 07:29:51 +08:00
# 2. t_station_price_schedule_scd
sql_price = """
DELETE FROM t_station_price_schedule_scd
WHERE station_hash IN (
SELECT station_hash FROM t_station_profile_scd WHERE operator = :operator
)
"""
result_price = await session.execute(text(sql_price), {"operator": operator})
2026-01-15 07:42:27 +08:00
logger.info(f"[{operator}] t_station_price_schedule_scd 已删除 {result_price.rowcount} 行。")
2026-01-15 07:29:51 +08:00
# 3. 最后删除主表 t_station_profile_scd
sql_profile = "DELETE FROM t_station_profile_scd WHERE operator = :operator"
result_profile = await session.execute(text(sql_profile), {"operator": operator})
2026-01-15 07:42:27 +08:00
logger.info(f"[{operator}] t_station_profile_scd 已删除 {result_profile.rowcount} 行。")
2026-01-15 07:29:51 +08:00
2026-01-15 07:42:27 +08:00
logger.info(f"[{operator}] 数据库记录清理完成。")
2026-01-15 07:29:51 +08:00
except Exception as e:
2026-01-15 07:42:27 +08:00
logger.error(f"[{operator}] 数据库清理失败: {e}")
2026-01-15 07:29:51 +08:00
# 2. Redis 清理
try:
keys = await redis_kit.keys(pattern)
if keys:
2026-01-15 07:42:27 +08:00
logger.info(f"[{operator}] 匹配到 {len(keys)} 个 Redis 键,正在删除...")
2026-01-15 07:29:51 +08:00
await redis_kit.delete(*keys)
2026-01-15 07:42:27 +08:00
logger.info(f"[{operator}] Redis 缓存清理完成。")
2026-01-15 07:29:51 +08:00
else:
2026-01-15 07:42:27 +08:00
logger.info(f"[{operator}] 未匹配到模式为 '{pattern}' 的 Redis 键。")
2026-01-15 07:29:51 +08:00
except Exception as e:
2026-01-15 07:42:27 +08:00
logger.error(f"[{operator}] Redis 清理失败: {e}")
async def main():
print("\n" + "="*30)
print(" 供应商数据清理工具")
print("="*30)
for key, info in VENDORS.items():
print(f"{key}. {info['name']}")
print("0. 全部清理")
print("q. 退出")
print("-" * 30)
choice = input("请输入选择的编号: ").strip().lower()
if choice == 'q':
return
selected_vendors = []
if choice == '0':
selected_vendors = list(VENDORS.values())
elif choice in VENDORS:
selected_vendors = [VENDORS[choice]]
else:
print("无效的选择,请重新运行脚本。")
return
# 初始化资源
db = Db(db_url=DB_URL)
await db.init_db()
redis_kit = RedisKit()
try:
for vendor in selected_vendors:
await clear_vendor_data(db, redis_kit, vendor)
finally:
logger.info("正在关闭数据库连接...")
await db.close()
2026-01-15 07:29:51 +08:00
if __name__ == "__main__":
2026-01-15 07:40:53 +08:00
Win32Patch.patch()
2026-01-15 07:42:27 +08:00
try:
asyncio.run(main())
except KeyboardInterrupt:
pass
except Exception as e:
logger.error(f"程序运行异常: {e}")