# upgrade_sql **Repository Path**: MM-Q/upgrade_sql ## Basic Information - **Project Name**: upgrade_sql - **Description**: ctc自动升级工具sql执行模块 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-02-13 - **Last Updated**: 2026-03-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # PostgreSQL SQL 执行脚本 一个灵活的 Bash 脚本,用于批量执行 PostgreSQL SQL 文件。支持主机直连和 Docker 容器两种执行环境。 ## 功能特性 - **双环境支持**:支持本地 PostgreSQL 和 Docker 容器执行 - **批量执行**:自动扫描目录,按文件名排序执行多个 SQL 文件 - **执行控制**:出错停止/继续、预览模式、强制跳过确认 - **完整日志**:记录执行过程和 SQL 输出到固定日志文件 - **灵活配置**:所有参数集中到脚本顶部,易于修改 ## 快速开始 ### 1. 配置脚本 编辑 `execute_sql.sh` 顶部的可配置参数区域: **Host 模式(默认):** ```bash EXEC_ENV="host" DB_HOST="localhost" DB_PORT="5432" DB_NAME="postgres" DB_USER="postgres" DB_PASSWORD="" ``` **Docker 模式:** ```bash EXEC_ENV="docker" DOCKER_CONTAINER="my-postgres-container" DB_NAME="postgres" DB_USER="postgres" DB_PASSWORD="" ``` ### 2. 放置 SQL 文件 将 `.sql` 文件放入 `sql/` 目录,按文件名前缀控制执行顺序: ``` sql/ ├── 00_create_database.sql -- 先执行:建库 ├── 01_create_tables.sql -- 再执行:建表 └── 02_insert_data.sql -- 最后执行:插入数据 ``` ### 3. 执行脚本 ```bash # 普通执行 bash execute_sql.sh # 预览模式(只显示不执行) bash execute_sql.sh --dry-run # 强制模式(跳过确认,等同于 SKIP_CONFIRM=true) bash execute_sql.sh -f # 查看帮助 bash execute_sql.sh --help ``` ## 配置参数说明 ### 执行环境配置 | 参数 | 说明 | 默认值 | |------|------|--------| | `EXEC_ENV` | 执行环境:`host`(主机) / `docker`(Docker容器) | `host` | | `DOCKER_CONTAINER` | Docker 容器名称或ID(docker模式必填) | - | ### 数据库连接配置 | 参数 | 说明 | 适用环境 | 默认值 | |------|------|----------|--------| | `PSQL_PATH` | psql 可执行文件完整路径 | host | - | | `DB_HOST` | 数据库主机地址 | host | `localhost` | | `DB_PORT` | 数据库端口 | host | `5432` | | `DB_NAME` | 数据库名称 | 全部 | `postgres` | | `DB_USER` | 数据库用户名 | 全部 | `postgres` | | `DB_PASSWORD` | 数据库密码 | 全部 | - | ### 执行选项 | 参数 | 说明 | 默认值 | |------|------|--------| | `SQL_DIR` | SQL 文件存放目录 | `./sql` | | `SQL_FILE_PATTERN` | SQL 文件匹配模式 | `*.sql` | | `EXECUTE_ORDER` | 执行顺序:`asc`(升序) / `desc`(降序) | `asc` | | `DRY_RUN` | 预览模式:`true`(只显示) / `false`(执行) | `false` | | `STOP_ON_ERROR` | 出错停止:`true`(停止) / `false`(继续) | `true` | | `SKIP_CONFIRM` | 跳过确认:`true`(直接执行) / `false`(询问) | `true` | | `LOG_ENABLED` | 启用日志:`true` / `false` | `true` | | `LOG_DIR` | 日志存放目录 | `./logs` | ### 自动创建数据库配置 | 参数 | 说明 | 默认值 | 可选值 | |------|------|--------|--------| | `AUTO_CREATE_DB` | 数据库不存在时自动创建 | `false` | `true` / `false` | | `CREATE_DB_TEMPLATE` | 建库模板 | `template0` | `template0`(纯净), `template1`(带扩展) | | `CREATE_DB_ENCODING` | 数据库编码 | `UTF8` | `UTF8`, `GBK`, `SQL_ASCII`, `LATIN1` 等 | | `CREATE_DB_LC_COLLATE` | 排序规则 | `en_US.utf8` | `en_US.utf8`, `C`, `zh_CN.utf8`, `POSIX` 等 | | `CREATE_DB_LC_CTYPE` | 字符分类 | `en_US.utf8` | `en_US.utf8`, `C`, `zh_CN.utf8`, `POSIX` 等 | | `CREATE_DB_OWNER` | 数据库拥有者 | `postgres` | 任意已存在的 PostgreSQL 用户 | ## 使用示例 ### Host 模式示例 ```bash # 配置 EXEC_ENV="host" PSQL_PATH="/usr/bin/psql" # 可选,留空使用环境变量 DB_HOST="192.168.1.100" DB_PORT="5432" DB_NAME="myapp" DB_USER="postgres" DB_PASSWORD="secret" ``` ### Docker 模式示例 ```bash # 配置 EXEC_ENV="docker" DOCKER_CONTAINER="pg13-instance" DB_NAME="myapp" DB_USER="postgres" DB_PASSWORD="secret" # Docker 模式说明: # - 自动校验容器存在性、运行状态、psql 可用性 # - SQL 文件通过 stdin 方式传入容器,无需 volume 挂载 # - DB_HOST/DB_PORT 在 docker 模式下可忽略 ``` ## 文件命名规范 脚本按文件名排序执行,建议添加数字前缀控制顺序: ``` 00_create_database.sql -- 建库(连接到 postgres) 01_create_tables.sql -- 建表 02_create_indexes.sql -- 建索引 03_insert_data.sql -- 插入数据 04_update_data.sql -- 更新数据 ``` ## 日志说明 - **日志位置**:`logs/execute.log` - **写入方式**:追加写入,保留历史记录 - **日志内容**:执行时间、配置信息、SQL 执行输出、错误信息 ### 日志示例 ``` [2025-02-09 10:30:15] [INFO] PostgreSQL SQL 执行脚本启动 [2025-02-09 10:30:15] [INFO] 执行环境: docker [2025-02-09 10:30:15] [SUCCESS] Docker 容器 'pg13' 验证通过 ... ========== 01_create_tables.sql ========== CREATE TABLE CREATE INDEX ============================== ``` ## 注意事项 ### 自动创建数据库 脚本支持在目标数据库不存在时自动创建: **配置方式:** ```bash AUTO_CREATE_DB=true DB_NAME="myapp_db" ``` **命令行方式:** ```bash bash execute_sql.sh --db myapp_db --auto-create-db ``` **建库参数说明:** | 参数 | 可选值 | 说明 | |------|--------|------| | `CREATE_DB_TEMPLATE` | `template0` / `template1` | `template0` 是纯净模板,推荐使用;`template1` 可能包含额外扩展但可能与字符集冲突 | | `CREATE_DB_ENCODING` | `UTF8` / `GBK` / `SQL_ASCII` / `LATIN1` | 数据库编码,UTF8 最通用 | | `CREATE_DB_LC_COLLATE` | `en_US.utf8` / `C` / `zh_CN.utf8` / `POSIX` | 字符串排序规则,影响 ORDER BY 和比较操作 | | `CREATE_DB_LC_CTYPE` | `en_US.utf8` / `C` / `zh_CN.utf8` / `POSIX` | 字符分类规则,影响大小写转换和正则匹配 | **常用 Locale 说明:** - `en_US.utf8`:美式英语,不区分大小写排序,适合国际化应用 - `C` / `POSIX`:按字节排序,速度最快,但不符合语言习惯 - `zh_CN.utf8`:中文环境,适合中文排序 **故障排查:** 如果遇到字符集冲突错误(如 `incompatible with the collation of the template database`),请使用 `CREATE_DB_TEMPLATE="template0"`。 ### 手动建库脚本特殊处理 如果不使用自动建库,PostgreSQL 的 `CREATE DATABASE` 有以下限制: 1. 必须在 `postgres` 数据库上执行 2. 不能在事务块中执行 3. 如果数据库已存在会报错 **建议做法:** 1. 先配置 `DB_NAME="postgres"` 执行建库脚本 2. 修改配置 `DB_NAME="myapp_db"` 执行其他脚本 3. 或设置 `STOP_ON_ERROR=false` 让脚本继续执行 ### Docker 模式 - 确保执行脚本的用户有权限访问 Docker 守护进程 - 容器内必须安装 PostgreSQL 客户端 (`psql`) - SQL 文件编码需与容器内 PostgreSQL 期望的编码一致 ### 密码安全 - 建议通过环境变量 `PGPASSWORD` 或 `.pgpass` 文件设置密码 - 避免在脚本中明文存储生产环境密码 ## 目录结构 ``` upgrade_sql/ ├── execute_sql.sh # 主执行脚本 ├── sql/ # SQL 文件目录 │ ├── 00_create_database.sql │ ├── 01_create_tables.sql │ └── 02_insert_data.sql └── logs/ # 日志目录 └── execute.log ``` ## 故障排查 | 问题 | 解决方案 | |------|----------| | 未找到 psql 命令 | 安装 PostgreSQL 客户端,或在 `PSQL_PATH` 中指定完整路径 | | 容器不存在 | 检查 `DOCKER_CONTAINER` 配置,运行 `docker ps` 确认容器名称 | | 容器内无 psql | 确保容器镜像包含 PostgreSQL 客户端 | | 数据库连接失败 | 检查 `DB_HOST`、`DB_PORT`、`DB_USER`、`DB_PASSWORD` | | 建库报错 | 确保连接到 `postgres` 数据库,或使用 `template0` 模板 | | 字符集冲突 | 建库时添加 `TEMPLATE = template0` | ## 命令行参数 | 参数 | 说明 | |------|------| | `--db ` | 指定数据库名称(覆盖配置中的 DB_NAME) | | `--sql-dir ` | 指定 SQL 文件目录(覆盖配置中的 SQL_DIR) | | `--auto-create-db` | 数据库不存在时自动创建 | | `--dry-run` | 预览模式,只显示待执行文件 | | `-f, --force` | 强制执行,跳过确认提示 | | `-h, --help` | 显示帮助信息 | **使用示例:** ```bash # 使用默认配置执行 bash execute_sql.sh # 临时指定数据库和目录 bash execute_sql.sh --db myapp_db --sql-dir ./sql/migrations # 自动创建数据库(如果不存在) bash execute_sql.sh --db myapp_db --auto-create-db # 预览模式(不实际执行) bash execute_sql.sh --db myapp_db --dry-run # 强制执行(跳过确认) bash execute_sql.sh --db myapp_db -f ```