自动排队生成量化因子挖掘任务,心跳派发后将高 IC 因子入库。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-11 01:49:16 +08:00
parent f0b35e6b34
commit 598cecad5f
11 changed files with 529 additions and 23 deletions
+72 -9
View File
@@ -73,15 +73,15 @@ def upgrade_schema() -> None:
"ON compute_nodes (hardware_fingerprint)"
)
index_ready = "compute_nodes" in tables and ("node_index" in node_columns or any("node_index" in item for item in statements))
if not statements and not need_username_index and not index_ready:
return
with engine.begin() as conn:
for statement in statements:
conn.execute(text(statement))
if need_username_index:
conn.execute(text("CREATE UNIQUE INDEX IF NOT EXISTS uq_users_username ON users (username)"))
if index_ready:
_backfill_node_index(conn, "recovery_days" in node_columns or any("recovery_days" in item for item in statements))
if statements or need_username_index or index_ready:
with engine.begin() as conn:
for statement in statements:
conn.execute(text(statement))
if need_username_index:
conn.execute(text("CREATE UNIQUE INDEX IF NOT EXISTS uq_users_username ON users (username)"))
if index_ready:
_backfill_node_index(conn, "recovery_days" in node_columns or any("recovery_days" in item for item in statements))
_relax_task_node_id()
def _backfill_node_index(conn, has_recovery: bool) -> None:
@@ -97,6 +97,69 @@ def _backfill_node_index(conn, has_recovery: bool) -> None:
conn.execute(text("UPDATE compute_nodes SET recovery_days = 30 WHERE node_index BETWEEN 1 AND 20"))
def _relax_task_node_id(bind=None) -> None:
"""旧库 compute_tasks.node_id 为 NOT NULL,排队任务需要改成可空。SQLite 不能直接改空约束,整表重建。"""
target = bind or engine
inspector = inspect(target)
if "compute_tasks" not in inspector.get_table_names():
return
columns = {column["name"]: column for column in inspector.get_columns("compute_tasks")}
node_column = columns.get("node_id")
if node_column is None or node_column.get("nullable", True):
return
names = [
name
for name in (
"id",
"node_id",
"task_type",
"payload",
"status",
"push_status",
"push_error",
"dispatched_at",
"deadline_at",
"responded_at",
"success",
"result",
)
if name in columns
]
copied = ", ".join(names)
with target.connect().execution_options(isolation_level="AUTOCOMMIT") as conn:
conn.execute(text("PRAGMA foreign_keys=OFF"))
conn.execute(text("DROP TABLE IF EXISTS compute_tasks_queue"))
conn.execute(
text(
"""
CREATE TABLE compute_tasks_queue (
id VARCHAR(36) NOT NULL PRIMARY KEY,
node_id INTEGER,
task_type VARCHAR(32) NOT NULL,
payload JSON NOT NULL,
status VARCHAR(16) NOT NULL,
push_status VARCHAR(16) NOT NULL,
push_error VARCHAR(255),
dispatched_at DATETIME NOT NULL,
deadline_at DATETIME NOT NULL,
responded_at DATETIME,
success BOOLEAN,
result JSON,
FOREIGN KEY(node_id) REFERENCES compute_nodes (id)
)
"""
)
)
conn.execute(text(f"INSERT INTO compute_tasks_queue ({copied}) SELECT {copied} FROM compute_tasks"))
conn.execute(text("DROP TABLE compute_tasks"))
conn.execute(text("ALTER TABLE compute_tasks_queue RENAME TO compute_tasks"))
conn.execute(text("CREATE INDEX IF NOT EXISTS ix_compute_tasks_node_id ON compute_tasks (node_id)"))
conn.execute(text("CREATE INDEX IF NOT EXISTS ix_compute_tasks_status ON compute_tasks (status)"))
conn.execute(text("CREATE INDEX IF NOT EXISTS ix_task_node_status ON compute_tasks (node_id, status)"))
conn.execute(text("CREATE INDEX IF NOT EXISTS ix_task_dispatched_at ON compute_tasks (dispatched_at)"))
conn.execute(text("PRAGMA foreign_keys=ON"))
def _has_username_index(inspector) -> bool:
if "users" not in inspector.get_table_names():
return False