# 数据库配置与初始化说明(PostgreSQL / Redis) > 记录平台的 **PostgreSQL 账号密码**、**Redis 账号密码**、**数据库地址在代码中的配置位置**, > 以及**切换 PG 数据集时如何执行完整初始化 SQL**。 --- ## 1. 账号密码速查表 ### 1.1 PostgreSQL | 环境 | 地址 | 用户 | 密码 | 数据库 | 来源 | |------|------|------|------|--------|------| | 代码默认值 | `localhost:15432` | `yg_ft` | `change_me` | `yg_ft` | `config.py` / `session.py` 的 `DATABASE_URL` 兜底 | | Docker 部署 | `www.caoxiaozhu.com:5432` | `root` | `8811614287327Leo` | `yg_ft` | `docker/app/.env` 的 `DATABASE_URL` | | Docker 内置 Postgres(已注释) | `localhost:15432` | `root` | `8811614287327Leo` | `yg_ft` | `docker/app/docker-compose.yml` 注释掉的 postgres 服务 | > ⚠️ `change_me` 与 `8811614287327Leo` 均为默认/示例凭据,生产环境务必更换。 ### 1.2 Redis | 项 | 值 | 说明 | |----|-----|------| | 连接串 | `redis://:@redis:6379/0` | 已内嵌密码;docker 网络内服务名 `redis`,端口 6379,db 0 | | 对外端口 | `16379`(`REDIS_PORT`) | 宿主机映射 | | 密码 | `docker/app/.env` 的 `REDIS_PASSWORD` | 已启用 `requirepass` 鉴权 | | 镜像 | `redis:7-alpine` | 已开启 AOF(`--appendonly yes`)+ `requirepass` | > **当前后端代码未使用 Redis**:`redis` 包已列入 `requirements.txt`,`REDIS_URL` 通过 > docker-compose 注入容器,但全仓库 `backend/`、`compute/` 没有任何 `import redis` / > `Redis(...)` 连接代码。Redis 为后续功能预留;**即便如此仍已配置鉴权**, > 避免无密码实例对外暴露(纵深防御)。未来启用时按 `REDIS_URL` 连接即可。 > > 健康检查通过容器环境变量 `REDISCLI_AUTH` 认证,不在进程参数中泄露密码。 --- ## 2. 数据库地址在代码中的配置位置 ### 2.1 后端(backend) | 文件 | 作用 | 取值 | |------|------|------| | `backend/app/core/config.py` | **唯一权威配置**,`Settings.database_url` | `os.getenv("DATABASE_URL", "postgresql+psycopg://yg_ft:change_me@localhost:15432/yg_ft")` | | `backend/app/db/session.py` | SQLAlchemy 引擎(`get_db` / `session_scope`) | `os.getenv("DATABASE_URL", ...)` 同样兜底 | | `backend/app/db/platform_store.py` | **平台主存储**,直接用 psycopg 连接池 | 取 `settings.database_url`,`_psycopg_url()` 把 `postgresql+psycopg://` 转成 `postgresql://` | | `backend/app/modules/data_process/store.py` | 数据处理存储 | `get_settings().database_url` | > **环境变量加载顺序**:`config.py` 导入时会 `load_dotenv(backend/.env, override=True)`, > 即 **`backend/.env` 会覆盖系统环境变量**;docker 部署则直接由 compose 注入 `DATABASE_URL`。 > 最终优先级:`backend/.env` / compose 注入的环境变量 > 代码内默认值。 ### 2.2 部署配置(docker) | 文件 | 关键项 | |------|--------| | `docker/app/.env` | `DATABASE_URL`、`POSTGRES_USER`、`POSTGRES_PASSWORD`、`REDIS_URL`、`REDIS_PORT` | | `docker/app/docker-compose.yml` | `backend-api` 环境透传上述变量;`redis` 服务定义 | ```ini # docker/app/.env(节选) DATABASE_URL=postgresql+psycopg://root:8811614287327Leo@www.caoxiaozhu.com:5432/yg_ft POSTGRES_USER=root POSTGRES_PASSWORD=8811614287327Leo REDIS_PASSWORD=<强密码> # Redis requirepass(新增鉴权) REDIS_URL=redis://:@redis:6379/0 # 连接串内嵌密码 REDIS_PORT=16379 USE_BUILTIN_POSTGRES=false # 当前用共享外部库,内置 postgres 服务被注释 USE_BUILTIN_REDIS=true # Redis 用内置服务 ``` --- ## 3. 完整初始化 SQL ### 3.1 脚本位置 | 脚本 | 用途 | |------|------| | **`backend/app/db/sql/000_full_init.sql`** | **一键初始化脚本(新增)**:建库表 + 索引 + 种子数据,幂等,覆盖全部 39 张运行表 | | `backend/app/db/sql/001_platform_runtime.sql` | 平台核心表(应用启动自动执行) | | `backend/app/db/sql/002_governance.sql` | 治理表(应用启动自动执行) | | `backend/app/db/sql/003_tenant_quota.sql` | 租户配额列(应用启动自动执行) | | `backend/app/db/sql/003_model_path_governance.sql` | 模型可训练列(**应用不自动执行**,已并入完整脚本) | | `backend/app/db/sql/002_data_process.sql` | 数据处理表(**应用不自动执行**,已并入完整脚本) | | `docs/postgres-schema.sql` | ⚠️ **目标设计稿**(UUID/JSONB),与运行时代码不兼容,**不要用于初始化** | > **重要**:`docs/postgres-schema.sql` 是规划中的“目标 schema”(UUID 主键、`ft_platform` schema 等), > 运行时代码明确拒绝该结构(`002_data_process.sql` 检测到 `datasets.id` 非 TEXT 会直接报错)。 > 初始化请使用 **`000_full_init.sql`**。 ### 3.2 执行步骤(全新 PG 环境) **第 1 步:创建角色与数据库**(必须单独执行,不能放进事务) ```sql -- 以超级用户(如 postgres)连接: CREATE ROLE yg_ft LOGIN PASSWORD '请改为强密码'; CREATE DATABASE yg_ft OWNER yg_ft; -- 如需应用执行 CREATE EXTENSION 等,可再授予超级用户(按需): -- ALTER ROLE yg_ft SUPERUSER; ``` **第 2 步:执行完整初始化脚本** ```bash psql "postgresql://yg_ft:密码@:5432/yg_ft" \ -f backend/app/db/sql/000_full_init.sql ``` 脚本特点: - 全程一个事务(`BEGIN; ... COMMIT;`),失败自动回滚 - 所有 DDL 使用 `IF NOT EXISTS` / `ADD COLUMN IF NOT EXISTS`,**可重复执行** - 含 `DO $$...$$` 语句块,必须用 `psql` 执行(应用内部的按分号切分 `executescript()` 不适用) - 自动写入种子用户:`admin / admin123`、`operator / operator123`(登录后请改密) **第 3 步:校验** ```sql SELECT count(*) FROM pg_tables WHERE schemaname = 'public'; -- 应 ≥ 39 SELECT username, role, status FROM users; -- 应有 admin / operator ``` ### 3.3 执行方式对比(三种途径) | 方式 | 覆盖范围 | 命令 | |------|----------|------| | **A. 完整脚本(推荐,切换新库)** | 全部 39 表 + 索引 + 种子 | `psql ... -f 000_full_init.sql` | | B. 应用自动初始化 | 001 + 002_governance + 003_tenant_quota + 种子用户;**不含**数据处理表、`models.can_train`、`data_convert_tasks` | 应用首次调用 `get_platform_store()` 时 `ensure_schema()` 自动执行 | | C. 数据处理表单独安装 | `002_data_process.sql` 全部内容 | 在 `backend/` 目录下:`python -m app.modules.data_process.schema_cli --apply --yes`(或 `--check` 只读检查) | > **缺口说明**: > - `models.can_train`(训练预检用)只在 `003_model_path_governance.sql` 中创建,应用启动**不会**自动执行; > - `data_convert_tasks`(数据转换任务表)运行时代码引用但**原 SQL 脚本缺失**; > 已统一并入 `000_full_init.sql` 补齐。若现有库缺这两项,执行一次完整脚本即可幂等补上。 ### 3.4 完整脚本包含的表(39 张) **核心**:users、models、trained_models、model_lineage、model_artifacts、model_export_jobs、 datasets、dataset_files、compute_nodes、gpus、fine_tune_tasks、fine_tune_metrics、 fine_tune_checkpoints、compute_jobs、gpu_allocations、scheduler_locks、resource_replicas、 resource_sync_jobs、eval_tasks、eval_dimensions、compare_tasks、projects、project_members、 roles、sessions、acls **治理**:tenants、approval_templates、approval_instances、approval_steps、audit_logs、retention_policies **数据处理**:data_process_tasks、data_process_source_files、data_process_preview_items、 data_process_results、dataset_file_versions、dataset_records **数据转换**:data_convert_tasks(新增补齐) --- ## 4. 安全注意事项 1. **更换默认密码**:`change_me`(代码兜底)、`8811614287327Leo`(部署)、`admin123`/`operator123`(种子用户)、`REDIS_PASSWORD` 上线前必须更换。 2. **Redis 已加鉴权**:已配置 `requirepass` + `REDISCLI_AUTH` 健康检查;`REDIS_URL` 内嵌密码。若端口需暴露公网,仍建议用防火墙/安全组限制来源。 3. **`docker/*/.env` 已入库,含明文凭据**: - `backend/.env` 已被 `.gitignore` 排除; - 但 `docker/app/.env`、`docker/compute/.env` 目前被 git 跟踪(`git ls-files` 可见), 其中的 `DATABASE_URL`、`POSTGRES_PASSWORD`、`COMPUTE_SERVICE_TOKEN` 等均为明文。 - **建议**:轮换这些凭据,将 `docker/*/.env` 移出版本库(`git rm --cached`)并改用 部署侧机密注入(如 docker secrets / CI 变量 / 环境变量模板),保留 `.env.example` 作为模板。 4. **最小权限**:应用角色只需对业务库的 DML/DDL 权限,尽量避免 SUPERUSER。