81 lines
2.9 KiB
SQL
81 lines
2.9 KiB
SQL
-- 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"
|
||
'
|
||
);
|