81 lines
2.9 KiB
MySQL
81 lines
2.9 KiB
MySQL
|
|
-- 1. 重建定时任务表 (增加 python_code 支持动态逻辑)
|
|||
|
|
DROP TABLE IF EXISTS "public"."scheduled_jobs" CASCADE;
|
|||
|
|
|
|||
|
|
CREATE TABLE "public"."scheduled_jobs" (
|
|||
|
|
"id" SERIAL PRIMARY KEY,
|
|||
|
|
"name" VARCHAR(100) NOT NULL, -- 任务名称
|
|||
|
|
"cron_expression" VARCHAR(50) NOT NULL, -- CRON表达式
|
|||
|
|
"python_code" TEXT, -- 【核心】可执行的Python业务代码
|
|||
|
|
"is_active" BOOLEAN DEFAULT TRUE, -- 启停状态
|
|||
|
|
"last_run_at" TIMESTAMP, -- 上次执行时间
|
|||
|
|
"last_run_status" VARCHAR(20), -- 上次执行结果
|
|||
|
|
"next_run_at" TIMESTAMP, -- 下次预计执行时间
|
|||
|
|
"description" TEXT, -- 描述
|
|||
|
|
"created_at" TIMESTAMP DEFAULT NOW(),
|
|||
|
|
"updated_at" TIMESTAMP DEFAULT NOW()
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
-- 索引
|
|||
|
|
CREATE INDEX "idx_scheduled_jobs_active" ON "public"."scheduled_jobs" ("is_active");
|
|||
|
|
|
|||
|
|
-- 注释
|
|||
|
|
COMMENT ON TABLE "public"."scheduled_jobs" IS '定时任务调度配置表(支持动态Python代码)';
|
|||
|
|
COMMENT ON COLUMN "public"."scheduled_jobs"."python_code" IS '直接执行的Python代码体,上下文中可使用 db, logger 等变量';
|
|||
|
|
|
|||
|
|
-- 插入默认任务:每日同步位置
|
|||
|
|
INSERT INTO "public"."scheduled_jobs"
|
|||
|
|
("name", "cron_expression", "description", "is_active", "python_code")
|
|||
|
|
VALUES
|
|||
|
|
(
|
|||
|
|
'每日全量位置同步',
|
|||
|
|
'0 0 * * *',
|
|||
|
|
'每天UTC 0点同步所有活跃天体的最新位置数据',
|
|||
|
|
true,
|
|||
|
|
'# 这是一个动态任务示例
|
|||
|
|
# 可用变量: db (AsyncSession), logger (Logger)
|
|||
|
|
from app.services.db_service import celestial_body_service, position_service
|
|||
|
|
from app.services.horizons import horizons_service
|
|||
|
|
from datetime import datetime
|
|||
|
|
|
|||
|
|
logger.info("开始执行每日位置同步...")
|
|||
|
|
|
|||
|
|
# 获取所有活跃天体
|
|||
|
|
bodies = await celestial_body_service.get_all_bodies(db)
|
|||
|
|
active_bodies = [b for b in bodies if b.is_active]
|
|||
|
|
|
|||
|
|
count = 0
|
|||
|
|
now = datetime.utcnow()
|
|||
|
|
|
|||
|
|
for body in active_bodies:
|
|||
|
|
try:
|
|||
|
|
# 获取当天位置
|
|||
|
|
positions = await horizons_service.get_body_positions(
|
|||
|
|
body_id=body.id,
|
|||
|
|
start_time=now,
|
|||
|
|
end_time=now
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
if positions:
|
|||
|
|
# 这里的 save_positions 需要自己实现或确保 db_service 中有对应方法支持 list
|
|||
|
|
# 假设我们循环 save_position 或者 db_service 已有批量接口
|
|||
|
|
# 为简单起见,这里演示循环调用
|
|||
|
|
for p in positions:
|
|||
|
|
await position_service.save_position(
|
|||
|
|
body_id=body.id,
|
|||
|
|
time=p.time,
|
|||
|
|
x=p.x,
|
|||
|
|
y=p.y,
|
|||
|
|
z=p.z,
|
|||
|
|
source="nasa_horizons_cron",
|
|||
|
|
session=db
|
|||
|
|
)
|
|||
|
|
count += 1
|
|||
|
|
except Exception as e:
|
|||
|
|
logger.error(f"同步 {body.name} 失败: {e}")
|
|||
|
|
|
|||
|
|
logger.info(f"同步完成,共更新 {count} 个天体")
|
|||
|
|
# 脚本最后一行表达式的值会被作为 result 存储
|
|||
|
|
f"Synced {count} bodies"
|
|||
|
|
'
|
|||
|
|
);
|