#!/usr/bin/env bash # qihuo · PostgreSQL 一键部署 / 从 SQLite 迁移 # 用法: sudo bash scripts/deploy_postgres.sh # 可选: MIGRATE_SQLITE=1 自动从 /opt/qihuo/futures.db 迁移 set -euo pipefail APP_DIR="${APP_DIR:-/opt/qihuo}" PG_DB="${PG_DB:-qihuo}" PG_USER="${PG_USER:-qihuo}" PG_HOST="${PG_HOST:-127.0.0.1}" PG_PORT="${PG_PORT:-5432}" MIGRATE_SQLITE="${MIGRATE_SQLITE:-0}" if [ "$(id -u)" -ne 0 ]; then echo "请使用 root: sudo bash scripts/deploy_postgres.sh" exit 1 fi if [ ! -d "$APP_DIR" ]; then echo "错误: 应用目录不存在 $APP_DIR,请先 bash deploy.sh" exit 1 fi echo "==> 安装 PostgreSQL..." export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y postgresql postgresql-contrib echo "==> 创建数据库与用户..." if [ -z "${PG_PASSWORD:-}" ]; then PG_PASSWORD="$(python3 -c 'import secrets; print(secrets.token_urlsafe(16))')" fi sudo -u postgres psql -v ON_ERROR_STOP=1 < 写入 .env DATABASE_URL..." ENV_FILE="$APP_DIR/.env" if grep -q "^DATABASE_URL=" "$ENV_FILE" 2>/dev/null; then sed -i "s|^DATABASE_URL=.*|DATABASE_URL=${DATABASE_URL}|" "$ENV_FILE" else echo "" >>"$ENV_FILE" echo "# PostgreSQL(生产推荐,消除 SQLite 并发锁)" >>"$ENV_FILE" echo "DATABASE_URL=${DATABASE_URL}" >>"$ENV_FILE" echo "PG_POOL_MIN=2" >>"$ENV_FILE" echo "PG_POOL_MAX=20" >>"$ENV_FILE" fi echo "==> Python 依赖..." # shellcheck disable=SC1091 source "$APP_DIR/venv/bin/activate" pip install -q -r "$APP_DIR/requirements.txt" echo "==> 停止 qihuo(释放数据库连接)..." if pm2 describe qihuo &>/dev/null; then pm2 stop qihuo || true sleep 2 fi if [ "$MIGRATE_SQLITE" = "1" ]; then echo "==> 重置 PostgreSQL 库(迁移模式)..." sudo -u postgres psql -v ON_ERROR_STOP=0 -c \ "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname='${PG_DB}' AND pid <> pg_backend_pid();" \ >/dev/null 2>&1 || true sudo -u postgres dropdb --if-exists "${PG_DB}" sudo -u postgres createdb -O "${PG_USER}" "${PG_DB}" fi echo "==> 初始化 PostgreSQL 表结构..." cd "$APP_DIR" export DATABASE_URL export QIHUO_SKIP_INIT_DB=1 export QIHUO_INIT_ONLY=1 python3 -c "from app import init_db; init_db(); from db_conn import database_label; print('OK:', database_label())" unset QIHUO_SKIP_INIT_DB QIHUO_INIT_ONLY if [ "$MIGRATE_SQLITE" = "1" ] && [ -f "$APP_DIR/futures.db" ]; then echo "==> 从 SQLite 迁移数据..." python3 "$APP_DIR/scripts/migrate_sqlite_to_postgres.py" --sqlite "$APP_DIR/futures.db" if [ "${BACKUP_SQLITE:-1}" = "1" ]; then BAK="$APP_DIR/futures.db.pre_pg.$(date +%Y%m%d_%H%M%S)" cp -a "$APP_DIR/futures.db" "$BAK" echo " 已备份旧库: $BAK" fi elif [ -f "$APP_DIR/futures.db" ]; then echo "提示: 检测到 futures.db,如需迁移请: MIGRATE_SQLITE=1 bash scripts/deploy_postgres.sh" fi echo "==> 重启 PM2..." if pm2 describe qihuo &>/dev/null; then pm2 restart ecosystem.config.cjs --update-env else pm2 start "$APP_DIR/ecosystem.config.cjs" fi pm2 save echo "" echo "==========================================" echo " PostgreSQL 部署完成" echo " DATABASE_URL=${DATABASE_URL}" echo " 请妥善保存数据库密码: ${PG_PASSWORD}" echo " 文档: docs/POSTGRES.md" echo " 备份: 系统设置页 或 pg_dump / 自动备份" echo "=========================================="