Files
cmautobuy/client/src/db_schema.py
T

174 lines
5.6 KiB
Python
Raw Normal View History

"""SQLite 数据库结构和迁移定义。
每个版本对应一组按顺序执行的 SQL。新增数据库版本时,只能在
``MIGRATIONS`` 末尾增加版本,不能修改已经发布的迁移。
"""
SCHEMA_VERSION = 5
MIGRATION_1 = (
"""
CREATE TABLE pdd_tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
remote_task_id TEXT NOT NULL UNIQUE,
task_type TEXT NOT NULL
CHECK (task_type IN ('collect', 'purchase')),
goods_id TEXT,
goods_url TEXT NOT NULL,
title TEXT,
target_color TEXT,
target_size TEXT,
price_cent INTEGER
CHECK (price_cent IS NULL OR price_cent >= 0),
quantity INTEGER
CHECK (quantity IS NULL OR quantity > 0),
status TEXT NOT NULL DEFAULT 'claimed'
CHECK (status IN (
'claimed', 'running',
'result_pending', 'retry_wait',
'manual_review', 'succeeded',
'failed', 'cancelled'
)),
current_step TEXT,
priority INTEGER NOT NULL DEFAULT 0,
version INTEGER NOT NULL DEFAULT 1 CHECK (version > 0),
admin_payload TEXT NOT NULL DEFAULT '{}',
pdd_data TEXT,
retry_count INTEGER NOT NULL DEFAULT 0 CHECK (retry_count >= 0),
last_error_code TEXT,
last_error_message TEXT,
received_at TEXT NOT NULL,
started_at TEXT,
finished_at TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
)
""",
"""
CREATE INDEX idx_pdd_tasks_list
ON pdd_tasks(updated_at DESC, id DESC)
""",
"""
CREATE INDEX idx_pdd_tasks_status_type
ON pdd_tasks(status, task_type)
""",
"""
CREATE INDEX idx_pdd_tasks_goods_id
ON pdd_tasks(goods_id)
""",
"""
CREATE TABLE task_runs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task_id INTEGER NOT NULL,
attempt_id TEXT NOT NULL UNIQUE,
attempt_no INTEGER NOT NULL CHECK (attempt_no > 0),
device_address TEXT NOT NULL,
run_status TEXT NOT NULL
CHECK (run_status IN (
'running', 'succeeded', 'failed',
'cancelled', 'manual_review'
)),
current_step TEXT,
started_at TEXT NOT NULL,
finished_at TEXT,
irreversible_action_at TEXT,
order_submitted_at TEXT,
error_code TEXT,
error_message TEXT,
diagnostics_json TEXT,
artifact_directory TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
FOREIGN KEY (task_id) REFERENCES pdd_tasks(id) ON DELETE CASCADE,
UNIQUE (task_id, attempt_no)
)
""",
"""
CREATE INDEX idx_task_runs_task
ON task_runs(task_id, attempt_no DESC)
""",
"""
CREATE TABLE outbox_events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task_id INTEGER NOT NULL,
event_type TEXT NOT NULL
CHECK (event_type IN (
'collect_result', 'purchase_result',
'task_failure'
)),
idempotency_key TEXT NOT NULL UNIQUE,
payload_json TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending'
CHECK (status IN (
'pending', 'sending', 'sent', 'failed'
)),
attempt_count INTEGER NOT NULL DEFAULT 0
CHECK (attempt_count >= 0),
next_retry_at TEXT,
last_error TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
sent_at TEXT,
FOREIGN KEY (task_id) REFERENCES pdd_tasks(id) ON DELETE CASCADE
)
""",
"""
CREATE INDEX idx_outbox_pending
ON outbox_events(status, next_retry_at, id)
""",
"""
CREATE TABLE app_settings (
setting_key TEXT PRIMARY KEY,
value_json TEXT NOT NULL,
updated_at TEXT NOT NULL
)
""",
)
MIGRATION_2 = (
"""
ALTER TABLE task_runs ADD COLUMN result_data TEXT
""",
)
MIGRATION_3 = (
"""
ALTER TABLE pdd_tasks ADD COLUMN execution_mode TEXT NOT NULL DEFAULT 'dry_run'
CHECK (execution_mode IN ('dry_run', 'live'))
""",
)
2026-08-10 17:23:24 +08:00
MIGRATION_4 = (
"""
ALTER TABLE pdd_tasks ADD COLUMN removed_at TEXT
""",
"""
CREATE INDEX idx_pdd_tasks_visible_list
ON pdd_tasks(removed_at, updated_at DESC, id DESC)
""",
)
MIGRATION_5 = (
"ALTER TABLE pdd_tasks ADD COLUMN shop_name TEXT",
"""
UPDATE pdd_tasks
SET shop_name = TRIM(json_extract(pdd_data, '$.shop_name'))
WHERE pdd_data IS NOT NULL AND json_valid(pdd_data)
AND json_type(pdd_data, '$.shop_name') = 'text'
AND TRIM(json_extract(pdd_data, '$.shop_name')) <> ''
""",
)
2026-08-10 17:23:24 +08:00
MIGRATIONS = {
1: MIGRATION_1,
2: MIGRATION_2,
3: MIGRATION_3,
2026-08-10 17:23:24 +08:00
4: MIGRATION_4,
5: MIGRATION_5,
}