diff --git a/scripts/create_tables.py b/scripts/create_tables.py index 8bc1814..1845201 100644 --- a/scripts/create_tables.py +++ b/scripts/create_tables.py @@ -61,6 +61,69 @@ CREATE TABLE IF NOT EXISTS sd_features ( ) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci engine=innodb comment '功能/需求表'; """ +# pipeline-service v2 运行时表(原 init.py::_init_v2_tables 启动时建,现迁到部署期)。 +# 手写幂等 DDL:避开 json2ddl 的 DEFAULT ''N'' bug;索引内联避免重复建 Duplicate key name。 +# 铁律:运行期不做任何 schema 变更,DB 全部变化必须在部署期(build.sh → create_tables.py)完成。 +_V2_RUNTIME_TABLES = [ +""" +CREATE TABLE IF NOT EXISTS pipeline_user_memory ( + `id` varchar(32) NOT NULL, + `memory_key` varchar(64) NOT NULL, + `content` text NOT NULL, + `category` varchar(32) NOT NULL DEFAULT 'memory', + `scope` varchar(32) NOT NULL DEFAULT 'global', + `scope_id` varchar(64) NOT NULL DEFAULT '', + `priority` int(11) NOT NULL DEFAULT 0, + `access_count` int(11) NOT NULL DEFAULT 0, + `created_at` datetime NOT NULL DEFAULT current_timestamp(), + `updated_at` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), + PRIMARY KEY (`id`), + UNIQUE KEY `uk_memory` (`memory_key`,`category`), + KEY `idx_category_priority` (`category`,`priority`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +""", +""" +CREATE TABLE IF NOT EXISTS sd_deploy_accounts ( + `id` varchar(32) NOT NULL, + `user_id` varchar(32) NOT NULL, + `account_name` varchar(64) NOT NULL, + `deploy_dir` varchar(500) NOT NULL, + `status` varchar(20) NOT NULL DEFAULT 'active', + `sandbox_config` text, + `created_at` datetime NOT NULL DEFAULT current_timestamp(), + `updated_at` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), + PRIMARY KEY (`id`), + UNIQUE KEY `uk_account_name` (`account_name`), + UNIQUE KEY `uk_user_id` (`user_id`), + KEY `idx_status` (`status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +""", +""" +CREATE TABLE IF NOT EXISTS sd_work_envs ( + `id` varchar(32) NOT NULL, + `owner_type` varchar(10) NOT NULL, + `owner_id` varchar(32) NOT NULL, + `mode` varchar(10) NOT NULL DEFAULT 'local', + `remote_host` varchar(200), + `remote_port` int(11) DEFAULT 22, + `remote_user` varchar(100), + `remote_key_path` varchar(500), + `remote_dir` varchar(500), + `created_at` datetime NOT NULL DEFAULT current_timestamp(), + `updated_at` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), + PRIMARY KEY (`id`), + UNIQUE KEY `uk_owner` (`owner_type`,`owner_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +""", +] + +# v2 引擎列迁移(原 init.py::_init_v2_tables 启动时 ALTER 迁移,现迁到部署期,information_schema 幂等) +_V2_COLUMNS = { + "pipelines": {"agent_config": "text"}, + "sd_org_settings": {"agent_config": "text"}, + "pipeline_tasks": {"retry_count": "int NOT NULL DEFAULT 0", "last_error": "text"}, +} + def split_ddl(ddl): """按分号分割 DDL,跳过注释行和空语句。""" @@ -171,6 +234,29 @@ async def main(): except Exception as e: print(f' WARN: sd_features ensure failed: {e}') + # pipeline-service v2 运行时表(原启动时建,现迁到部署期幂等建表) + try: + for ddl in _V2_RUNTIME_TABLES: + await sor.execute(ddl, {}) + print(' tables: pipeline-service v2 runtime tables ensured (pipeline_user_memory/sd_deploy_accounts/sd_work_envs)') + except Exception as e: + print(f' WARN: v2 runtime tables ensure failed: {e}') + + # v2 引擎列迁移(原启动时 ALTER,现迁到部署期,information_schema 查列存在性幂等) + try: + for tbl, cols in _V2_COLUMNS.items(): + for col, ddl in cols.items(): + r = await sor.sqlExe( + "SELECT COUNT(*) as c FROM information_schema.COLUMNS " + "WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=${tbl}$ " + "AND COLUMN_NAME=${col}$", {"tbl": tbl, "col": col}) + await sor.sqlExe("COMMIT", {}) + if not r or getattr(r[0], 'c', 0) == 0: + await sor.execute(f"ALTER TABLE {tbl} ADD COLUMN {col} {ddl}", {}) + print(' migrate: v2 engine columns ensured (agent_config/retry_count/last_error)') + except Exception as e: + print(f' WARN: v2 engine column migrate failed: {e}') + if __name__ == '__main__': asyncio.run(main())