diff --git a/fam-edge/src/fam_edge/queue/queue_manager.py b/fam-edge/src/fam_edge/queue/queue_manager.py index d8d946b..fec169f 100644 --- a/fam-edge/src/fam_edge/queue/queue_manager.py +++ b/fam-edge/src/fam_edge/queue/queue_manager.py @@ -30,29 +30,45 @@ def _get_conn() -> sqlite3.Connection: return conn +_TASK_QUEUE_DDL = """ + CREATE TABLE {name} ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + nas_task_id INTEGER NOT NULL, + video_filename TEXT NOT NULL, + video_path TEXT NOT NULL, + camera_name TEXT DEFAULT '', + event_start_time TEXT DEFAULT '', + known_members_context TEXT DEFAULT '', + status TEXT DEFAULT 'PENDING', + result_json TEXT, + error_message TEXT, + failure_stage TEXT, + retry_count INTEGER DEFAULT 0, + created_at TEXT DEFAULT (datetime('now', '+8 hours')), + updated_at TEXT DEFAULT (datetime('now', '+8 hours')), + delivered INTEGER DEFAULT 0, + UNIQUE(nas_task_id) + ) +""" + + def _init_db(): os.makedirs(os.path.dirname(DB_PATH), exist_ok=True) conn = sqlite3.connect(DB_PATH) - conn.execute(""" - CREATE TABLE IF NOT EXISTS task_queue ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - nas_task_id INTEGER NOT NULL, - video_filename TEXT NOT NULL, - video_path TEXT NOT NULL, - camera_name TEXT DEFAULT '', - event_start_time TEXT DEFAULT '', - known_members_context TEXT DEFAULT '', - status TEXT DEFAULT 'PENDING', - result_json TEXT, - error_message TEXT, - failure_stage TEXT, - retry_count INTEGER DEFAULT 0, - created_at TEXT DEFAULT (datetime('now', '+8 hours')), - updated_at TEXT DEFAULT (datetime('now', '+8 hours')), - delivered INTEGER DEFAULT 0, - UNIQUE(nas_task_id) - ) - """) + # DEFAULT 约束固化在表 schema 中,CREATE TABLE IF NOT EXISTS 不会更新已存在的旧表 + # (旧表 DEFAULT 是 localtime,UTC 机器上=UTC)。检测到旧 schema 时重建表迁移。 + row = conn.execute( + "SELECT sql FROM sqlite_master WHERE type='table' AND name='task_queue'" + ).fetchone() + if row is not None and 'localtime' in (row[0] or ''): + conn.execute("BEGIN IMMEDIATE") + conn.execute(_TASK_QUEUE_DDL.format(name='task_queue_new')) + conn.execute("INSERT INTO task_queue_new SELECT * FROM task_queue") + conn.execute("DROP TABLE task_queue") + conn.execute("ALTER TABLE task_queue_new RENAME TO task_queue") + conn.commit() + conn.execute(_TASK_QUEUE_DDL.format(name='task_queue').replace( + 'CREATE TABLE task_queue', 'CREATE TABLE IF NOT EXISTS task_queue')) conn.execute("CREATE INDEX IF NOT EXISTS idx_status ON task_queue(status)") conn.execute("CREATE INDEX IF NOT EXISTS idx_delivered ON task_queue(delivered)") conn.commit() @@ -66,8 +82,9 @@ def enqueue(nas_task_id: int, video_filename: str, video_path: str, try: cur = conn.execute( "INSERT OR IGNORE INTO task_queue " - "(nas_task_id, video_filename, video_path, camera_name, event_start_time, known_members_context) " - "VALUES (?, ?, ?, ?, ?, ?)", + "(nas_task_id, video_filename, video_path, camera_name, event_start_time, " + "known_members_context, created_at, updated_at) " + "VALUES (?, ?, ?, ?, ?, ?, datetime('now','+8 hours'), datetime('now','+8 hours'))", (nas_task_id, video_filename, video_path, camera_name, event_start_time, known_members_context) ) conn.commit()