Windows 上从零装好 PostgreSQL + pgvector(含全部踩坑实录)

场景:公司机器禁装 Docker,必须本机直装 PG 并启用 pgvector。
环境:Windows 10/11,PostgreSQL 16(自定义安装路径 E:\pgSQL\16),pgvector 0.8.1。
全程实战记录,所有”奇怪报错”都来自真实尝试。


0. 路线选择

Windows 上启用 pgvector 有三条路:

方案 优点 缺点
Docker 镜像 pgvector/pgvector 5 分钟搞定 公司禁装 Docker 时不可用
下载社区预编译 DLL 不用编译 PG 主版本号必须严格对齐,新版本可能没人编
MSVC 源码编译 任何 PG 版本都能搞 流程长,坑多

本文走第三条。


1. 装 PostgreSQL

去 https://www.postgresql.org/download/windows/ 下载安装器。

关键勾选:

  • ☑️ Development files(默认不勾,必须手动勾上)
    • 不勾的话,PG 安装目录里没有 lib\postgres.lib,后面编译 pgvector 会报 LNK1181: cannot open input file 'postgres.lib'
  • 安装路径可以自定义,例如 E:\pgSQL\16(注意末尾的 \16 是大版本号子目录,默认结构)
  • 端口可能不是 5432:自定义安装时如果检测到 5432 被占,会自动偏移到 5433,后面所有命令都得带 -p 5433

装完确认目录里有这四个子目录:

1
2
3
4
5
E:\pgSQL\16\
├── bin\ (pg_config.exe, psql.exe, postgres.exe)
├── lib\ (postgres.lib ← 关键)
├── include\ (server\ 子目录是头文件)
└── share\ (extension\ 子目录将来放 vector.control)

lib\postgres.lib 不存在 → 回去重跑安装器补勾 Development files。


2. 装 Visual Studio Build Tools 2022

下载:https://visualstudio.microsoft.com/visual-cpp-build-tools/

必勾的工作负载:

  • ☑️ Desktop development with C++

右侧默认子项里确认这两项有勾:

  • ☑️ MSVC v143 - VS 2022 C++ x64/x86 build tools
  • ☑️ Windows 11 SDK(或 Windows 10 SDK,任一最新版即可)

⚠️ 如果只勾了”Desktop development with C++”但右侧 SDK 那项被反勾掉了,后面会报:

1
fatal error C1083: 无法打开包括文件: "crtdefs.h": No such file or directory

这个 crtdefs.h 来自 Windows SDK 的 UCRT,没装 SDK 就找不到。

装完约占 6-8 GB。


3. 编译 pgvector

3.1 打开正确的命令提示符

⚠️ 这是最容易踩的坑:必须用 x64 Native Tools Command Prompt for VS 2022,不要用:

  • 普通 cmd
  • 普通 PowerShell
  • Git Bash
  • “Developer Command Prompt for VS”(x86 的,不对)

开始菜单搜 “x64 Native Tools”,右键 → 以管理员身份运行(编译完要往 Program Files 或 PG 安装目录写文件,需要管理员权限)。

自检命令:

1
echo %INCLUDE%

正确的提示符里这条会输出一长串,包含 Windows Kits\10\include\...\ucrt、MSVC\...\include 等路径。如果输出是空的或者只有一两条,就是用错 cmd 了。

3.2 设 PGROOT、克隆、编译

1
2
3
4
5
6
set "PGROOT=E:\pgSQL\16"
cd /d %TEMP%
git clone --branch v0.8.1 https://github.com/pgvector/pgvector.git
cd pgvector
nmake /F Makefile.win
nmake /F Makefile.win install

PGROOT 必须指到含 bin / lib / include / share 四个子目录的那一层。验证:

1
2
dir "%PGROOT%\bin\pg_config.exe"
dir "%PGROOT%\lib\postgres.lib"

两条都能列出文件才能继续。

nmake install 阶段如果报”拒绝访问”,就是 cmd 不是管理员权限,关掉重开。

成功输出末尾会看到:

1
2
3
copy "vector.dll" "E:\pgSQL\16\lib\"
copy "vector.control" "E:\pgSQL\16\share\extension\"
copy "sql\vector--*.sql" "E:\pgSQL\16\share\extension\"

3.3 重启 PG 服务

管理员 PowerShell:

1
Restart-Service postgresql-x64-16

服务名末尾的数字对应 PG 大版本号;如果用的是 PG 17 就是 postgresql-x64-17。


4. 建库 + 启用扩展

⚠️ 如果 PG 装在非默认端口(如 5433),后面所有 psql 命令必须显式 -p 5433。

先确认端口:

1
2
Get-NetTCPConnection -LocalPort 5432 -State Listen -ErrorAction SilentlyContinue
Get-NetTCPConnection -LocalPort 5433 -State Listen -ErrorAction SilentlyContinue

哪条有输出,PG 就在哪个端口。

4.1 建库(统一用 UTF-8 编码,避开后面的中文 Windows 坑)

1
2
3
4
5
6
7
8
9
10
11
12
13
$env:PGPASSWORD = "你装PG时设的postgres密码"
$psql = "E:\pgSQL\16\bin\psql.exe"
$port = 5433 # 改成你实际的端口

# 用 template0 + LC_COLLATE 'C' 创建 UTF-8 库,绕开中文 locale
& $psql -U postgres -h localhost -p $port -c "CREATE DATABASE oa_agent_vector WITH ENCODING 'UTF8' TEMPLATE template0 LC_COLLATE 'C' LC_CTYPE 'C';"

# 业务用户
& $psql -U postgres -h localhost -p $port -c "CREATE USER oa_agent WITH PASSWORD 'your_pwd';"
& $psql -U postgres -h localhost -p $port -c "GRANT ALL ON DATABASE oa_agent_vector TO oa_agent;"

# PG 16 默认 public schema 对所有用户开放,无需额外授权
# PG 17+ 需要补一条:GRANT ALL ON SCHEMA public TO oa_agent;

为什么用 TEMPLATE template0 LC_COLLATE 'C' LC_CTYPE 'C':

  • 中文 Windows 装 PG 时,template1 继承的 locale 是 Chinese (Simplified)_China.936,直接 CREATE DATABASE ... ENCODING 'UTF8' 会因为 locale 和编码不匹配而失败
  • template0 是干净模板,配 LC_COLLATE 'C' LC_CTYPE 'C' 跳过本地化排序,永远稳

4.2 启用 pgvector 扩展

1
2
& $psql -U postgres -h localhost -p $port -d oa_agent_vector -c "CREATE EXTENSION vector;"
& $psql -U postgres -h localhost -p $port -d oa_agent_vector -c "\dx vector"

最后那条应该输出:

1
2
3
4
                       已安装的扩展列表
名称 | 版本 | 模式 | 描述
--------+--------+--------+--------------
vector | 0.8.1 | public | vector data type ...

看到 vector | 0.8.1 就成了。


5. 客户端连接配置(中文 Windows 必坑)

业务代码用 psycopg2 连接时,最容易踩两个坑:

5.1 UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xd6

1
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd6 in position 61: invalid continuation byte

0xd6 是 GBK 字节。两种来源:

A. 你的 DSN 字符串里有非 ASCII 字符

最常见:.env 里 DSN 末尾留了占位符没换(比如 password=你的密码 这种)。或者 .env 文件被存成了 GBK 编码。

验证:

1
python -c "from dotenv import load_dotenv; import os; load_dotenv(); v=os.getenv('VECTOR_DB_DSN'); print(repr(v)); print('non-ascii:', [c for c in v if ord(c) > 127])"

non-ascii 列表非空就是 DSN 不干净。修法:

  • 把密码改成纯字母数字(建议)
  • .env 文件必须保存为 UTF-8(VSCode 右下角点编码切到 UTF-8 重新保存)

B. PG 服务器的 lc_messages 是中文 locale,连接握手返回的状态消息是 GBK

psycopg2 连接时显式声明 client_encoding="UTF8",并在会话内把 lc_messages 切到 C:

1
2
3
4
import psycopg2
conn = psycopg2.connect(dsn, client_encoding="UTF8")
with conn.cursor() as cur:
cur.execute("SET lc_messages TO 'C';")

如果还不行,改 postgresql.conf:

1
lc_messages = 'C'

然后 Restart-Service postgresql-x64-16。

5.2 端口错了报 “database does not exist”

1
2
psycopg2.OperationalError: connection to server at "localhost" (::1), port 5433 failed:
FATAL: database "oa_agent_vector" does not exist

90% 的情况:你在 5432 那台 PG 里执行了 CREATE DATABASE,但代码连的是 5433。

修法:DSN 端口和 psql -p 参数对齐。


6. 完整收尾验证

业务侧用 SQLAlchemy / psycopg2 连接的话,DSN 格式:

1
postgresql://oa_agent:your_pwd@localhost:5433/oa_agent_vector

Python 验证脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import psycopg2
from pgvector.psycopg2 import register_vector
import numpy as np

conn = psycopg2.connect(
"postgresql://oa_agent:your_pwd@localhost:5433/oa_agent_vector",
client_encoding="UTF8",
)
register_vector(conn)

with conn.cursor() as cur:
cur.execute("DROP TABLE IF EXISTS demo_vec;")
cur.execute("CREATE TABLE demo_vec (id int, emb vector(3));")
cur.execute("INSERT INTO demo_vec VALUES (1, %s), (2, %s);",
(np.array([1, 2, 3], dtype=np.float32),
np.array([1, 2, 4], dtype=np.float32)))
cur.execute("SELECT id, emb <=> %s AS dist FROM demo_vec ORDER BY dist;",
(np.array([1, 2, 3], dtype=np.float32),))
for row in cur.fetchall():
print(row)

输出类似:

1
2
(1, 0.0)
(2, 0.0019...)

到这里整条链路就通了:PG 16 + pgvector 0.8.1 + Python 客户端,可以开始建业务表、灌 embedding、做向量检索。


7. 踩坑总结一句话版

按出现顺序:

  1. PG 安装器忘了勾 Development files → 没 postgres.lib → 编译报 LNK1181
  2. 编译时用了普通 cmd 而不是 x64 Native Tools Command Prompt → 找不到 crtdefs.h
  3. VS Build Tools 没装 Windows SDK → 同上找不到 crtdefs.h
  4. PG 装在 5433 但代码连 5432(或反过来)→ database does not exist
  5. .env 存成 GBK 或 DSN 含中文 → 0xd6 UnicodeDecodeError
  6. 建库没用 TEMPLATE template0 → 中文 locale 和 UTF-8 编码冲突,建库失败

每一条都是从”看错误信息”到”看清楚错误信息”之间的距离。


写于 2026-05-19,PostgreSQL 16 + pgvector 0.8.1 + VS Build Tools 2022(v14.41)。