update backend

This commit is contained in:
toom1996
2026-09-20 01:06:13 +08:00
parent f7ae917603
commit b99dc3dca1
115 changed files with 24732 additions and 10842 deletions

164
scripts/setup_pg_wsl.sh Normal file
View File

@ -0,0 +1,164 @@
#!/usr/bin/env bash
#
# setup_pg_wsl.sh — WSL (Ubuntu/Debian) 下一键装 PostgreSQL + pgvector 开发环境
#
# 用法(在 WSL 终端里,不要用 Windows 的 CMD/PowerShell 跑):
# sudo bash setup_pg_wsl.sh
#
# 三态幂等:
# 1) 未安装 -> 安装 + 启动
# 2) 已安装未运行 -> 仅启动
# 3) 已安装且运行 -> 完全不动(不重装 / 不重启;仅幂等确保库/用户/扩展存在)
#
# 仅用于本地开发 / 迁移验证,生产环境请改强密码并单独评审配置。
#
set -euo pipefail
# ============================ 配置(按需修改)============================
PG_VERSION=16 # PostgreSQL 大版本,pgvector HNSW 在 13+ 均可用
DB_NAME=fashion # 业务库名(替换成你的项目库)
DB_USER=fashion # 应用账号
DB_PASS="fashion_dev_2026" # 仅本地开发;生产务必换成强密码
# =========================================================================
log() { echo -e "\033[32m==>\033[0m $*"; }
# 需要 root
if [ "$(id -u)" -ne 0 ]; then
echo "请以 root 运行: sudo bash $0"; exit 1
fi
# 发行版探测(仅提示,不强制)
if [ -r /etc/os-release ]; then
. /etc/os-release
log "检测到发行版: ${PRETTY_NAME:-unknown}"
case "${ID:-}" in
ubuntu|debian) ;;
*) echo "⚠️ 本脚本面向 Ubuntu/Debian WSL,其他发行版请自行调整 apt 命令";;
esac
fi
# PG 是否在运行(用超级用户连 postgres 库试探,对活实例零副作用)
pg_is_running() { sudo -u postgres psql -d postgres -tAc "SELECT 1" >/dev/null 2>&1; }
# 1) 已装则跳过安装(不重装)
if command -v psql >/dev/null 2>&1; then
log "PostgreSQL 已安装 ($(psql --version 2>/dev/null || echo unknown)),跳过安装"
else
log "安装依赖并添加 PostgreSQL 官方 apt 源"
# 关键:先清掉旧的 pgdg 源与坏 key,否则下面第一次 apt-get update 会因旧 .asc key
# 报 "not signed" 返回非零,被 set -e 直接退出,导致修 key 步骤永远没机会执行。
rm -f /etc/apt/sources.list.d/pgdg.list
rm -f /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc
apt-get update -y
apt-get install -y curl ca-certificates gnupg lsb-release
# 加 pgdg 源(官方标准:armored key -> dearmor 成 .gpg,signed-by 指向 .gpg)
install -d /usr/share/postgresql-common/pgdg
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc -o /tmp/pgdg-key.asc
gpg --dearmor -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.gpg /tmp/pgdg-key.asc
chmod 644 /usr/share/postgresql-common/pgdg/apt.postgresql.org.gpg
echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.gpg] https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" \
> /etc/apt/sources.list.d/pgdg.list
apt-get update -y
apt-get install -y "postgresql-$PG_VERSION" "postgresql-client-$PG_VERSION"
fi
# 2) pgvector(已可用则跳过,不重装)
if sudo -u postgres psql -d postgres -tAc "SELECT 1 FROM pg_available_extensions WHERE name='vector'" 2>/dev/null | grep -q 1; then
log "pgvector 已可用,跳过"
else
log "安装 pgvector 扩展"
if apt-get install -y "postgresql-$PG_VERSION-pgvector"; then
:
else
echo "apt 无 pgvector 包,改用源码编译..."
apt-get install -y "build-essential" "postgresql-server-dev-$PG_VERSION" git
tmp=$(mktemp -d)
git clone --depth 1 https://github.com/pgvector/pgvector.git "$tmp/pgvector"
make -C "$tmp/pgvector"
make -C "$tmp/pgvector" install
rm -rf "$tmp"
fi
fi
# 3) 仅在未运行时启动;已在运行则完全不动
if pg_is_running; then
log "PostgreSQL 已在运行,跳过启动 / 重启"
else
log "启动 PostgreSQL"
pg_ctlcluster "$PG_VERSION" main start 2>/dev/null \
|| service postgresql start 2>/dev/null \
|| systemctl start postgresql
# 等实例就绪(最多 15s)
for i in $(seq 1 15); do
if pg_is_running; then break; fi
sleep 1
done
if ! pg_is_running; then
echo "❌ PostgreSQL 启动失败,请查日志: journalctl -u postgresql 或 /var/log/postgresql/"; exit 1
fi
fi
# 4) 幂等确保库/用户/扩展(对运行中实例无副作用,不重启)
log "确保用户、数据库与 pgvector 扩展存在(幂等)"
sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '$DB_PASS';"
sudo -u postgres psql -c "CREATE ROLE $DB_USER LOGIN PASSWORD '$DB_PASS';" 2>/dev/null \
|| echo " 角色 $DB_USER 已存在,跳过"
sudo -u postgres psql -tc "SELECT 1 FROM pg_database WHERE datname='$DB_NAME'" | grep -q 1 \
|| sudo -u postgres createdb -O "$DB_USER" "$DB_NAME"
sudo -u postgres psql -d "$DB_NAME" -c "CREATE EXTENSION IF NOT EXISTS vector;"
# 5) 本地访问配置:仅当 listen 还不是 localhost 才改;运行中走在线 reload,绝不重启
PGCONF="/etc/postgresql/$PG_VERSION/main/postgresql.conf"
if [ -f "$PGCONF" ]; then
if grep -q "^listen_addresses = 'localhost'" "$PGCONF"; then
: # 已配置,无需改动
else
log "调整 listen_addresses=localhost(仅本地)"
sed -i "s/^#*listen_addresses = .*/listen_addresses = 'localhost'/" "$PGCONF"
if pg_is_running; then
pg_ctlcluster "$PG_VERSION" main reload 2>/dev/null \
|| sudo -u postgres psql -d postgres -c "SELECT pg_reload_conf();" >/dev/null 2>&1 \
|| echo " ⚠️ reload 失败,配置将在下次重启生效"
else
log "(实例未运行,配置将在下次启动时生效)"
fi
fi
fi
# 6) 验证
log "验证安装"
sudo -u postgres psql -d "$DB_NAME" \
-c "SELECT version();" \
-c "SELECT extname, extversion FROM pg_extension WHERE extname='vector';"
cat <<EOF
✅ PostgreSQL $PG_VERSION + pgvector 就绪(WSL)
连接串 : postgres://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME
命令行 : psql -h localhost -U $DB_USER -d $DB_NAME
数据目录: /var/lib/postgresql/$PG_VERSION/main
⚠️ WSL 注意事项
- WSL 重启后 PG 不会自动起,手动: sudo service postgresql start
- 想开机自启:在 Windows 侧建 .bat 执行 wsl -u root service postgresql start
或在 /etc/wsl.conf 加 [boot] command="service postgresql start"
- 本脚本密码为弱密码,仅本地开发;生产请更换并 review pg_hba.conf
(可选)CLIP / DINOv2 embedding 表示例:
CREATE TABLE image_embedding (
id BIGSERIAL PRIMARY KEY,
image_uid VARCHAR(32) NOT NULL, -- 对应你现有的 hashid uid
kind SMALLINT NOT NULL, -- 0=runway 1=street
embedding vector(512), -- 512 维特征(CLIP ViT-B/32 或 DINOv2)
created_at INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX image_embedding_vec_idx
ON image_embedding USING hnsw (embedding vector_cosine_ops);
-- 去重查询:找最近邻
SELECT image_uid, 1 - (embedding <=> '[...]'::vector) AS sim
FROM image_embedding
WHERE kind = 0
ORDER BY embedding <=> '[...]'::vector
LIMIT 20;
EOF