Windows 上 PostgreSQL 12 安装 PostGIS 3.4.2 完整指南:从 bundle 包到空间查询

📅 发布时间:2026/10/3 18:10:59
Windows 上 PostgreSQL 12 安装 PostGIS 3.4.2 完整指南:从 bundle 包到空间查询
简介postgis-bundle-pg12-3.4.2x64.zip 是面向 PostgreSQL 12 用户的 PostGIS 3.4.2 空间数据库扩展安装包适用于从事地理信息系统开发、空间数据分析与城市规划、环境监测、交通导航等场景的开发者与 GIS 工程师。PostGIS 在对象关系型数据库之上增加空间数据存储与管理能力兼容 OGC 简单特征访问标准可与 QGIS、GRASS GIS、uDig 等软件协同工作支持二维至四维空间对象、空间索引、坐标投影转换以及 shapefile、GeoJSON、KML、GPX 等格式读写。压缩包共 1281 个文件约 129.44MB以 895 个 sql 脚本、78 个 dll 动态库、74 个 csv 数据文件为主另含 tif 栅格、control 扩展控制文件、pl 脚本及 xml、json 配置等覆盖扩展注册、数据装载与示例数据等模块。目前已有 112 人学习下载适合需要快速部署空间数据库、研究扩展目录结构或搭建 GIS 实验环境的读者参考。1. postgis-bundle-pg12-3.4.2x64.zip 到底是什么一次把 Windows 上的空间数据库装明白如果你在 Windows 上装过 PostGIS大概率经历过这种场景PostgreSQL 12 装好了pgAdmin 能连上结果一执行CREATE EXTENSION postgis;就报could not open extension control file或者干脆提示找不到postgis-3.dll。搜「postgis安装失败」出来的答案一半让你去改 PATH一半让你重装 PostgreSQL照着做还是不行。postgis-bundle-pg12-3.4.2x64.zip这个文件名其实已经把答案写清楚了它是给 PostgreSQL 12、64 位 Windows 用的 PostGIS 3.4.2 打包版本bundle 的意思是「捆绑包」里面不只有 PostGIS 扩展本身还带了 GEOS、PROJ、GDAL 这些空间计算依赖库。换句话说它解决的核心问题就是让你不用自己编译 GDAL 和 PROJ直接把空间能力挂到已有的 PG12 上。这篇内容适合两类人一是在 Windows 上被 PostGIS 依赖折腾过的后端或 GIS 开发二是需要在本机或内网快速搭一套空间数据库做验证的数据工程。接下来我会按「先搞懂包里有什么、再动手装、最后排错」的顺序讲透。2. 拆开这个 bundle目录结构、依赖关系和版本匹配逻辑2.1 bundle 和普通 PostGIS 安装包的区别在哪很多人第一次看到postgis-bundle会以为是某个第三方魔改版其实它是 PostGIS 官方在 Windows 上的一种分发形式。普通安装方式要么用 StackBuilder依赖网络、版本受限于官方列表要么自己下源码编译Windows 上编译 GDAL 是出了名的血泪经验。bundle 包把编译好的二进制、依赖 DLL、SQL 脚本、扩展控制文件全部塞进一个压缩包解压后按目录对应复制到 PostgreSQL 安装目录即可。它和「PostGIS 单独安装包」最大的区别在于依赖处理。PostGIS 本身不是一个孤立扩展它依赖三个底层库依赖库作用缺失时的典型报错GEOS几何运算相交、缓冲、拓扑could not load library postgis-3.dllPROJ坐标投影与转换transform: couldnt project pointGDAL栅格与多格式数据读写rt_raster_from_gdal_dataset相关错误普通安装包往往只给 PostGIS 自己的文件依赖要你另外配。bundle 把这些一起打包所以体积会明显大一些但换来的是「复制完就能用」。这也是为什么搜 postgis 安装失败的人最后大多被建议换成 bundle 版本。2.2 文件名里的 pg12、3.4.2、x64 分别约束了什么postgis-bundle-pg12-3.4.2x64.zip这个名字不是随便起的每个字段都是硬约束装错一个就失败pg12对应 PostgreSQL 12 的大版本。PostGIS 的二进制和 PostgreSQL 的 ABI 是绑定的PG12 编译出来的扩展不能直接丢进 PG13/14/15反之亦然。你本机是 PG12.x 的任意小版本12.0 到 12.22都可以用但跨大版本不行。3.4.2PostGIS 的版本号。3.4 系列要求 PostgreSQL 最低 12所以这个组合是官方支持的。3.4.2 属于 3.4 的补丁版本修了一些几何解析和栅格相关的 bug。x6464 位。必须和你的 PostgreSQL 位数一致。如果你装的是 32 位 PG现在很少见这个包用不了。提示确认自己 PostgreSQL 版本和位数的命令是SELECT version();输出里会带64-bit字样。别靠安装目录名猜。2.3 解压后你会看到哪些目录把 zip 解压到一个临时目录典型结构是这样的不同小版本目录名可能略有差异但层级一致postgis-bundle-pg12-3.4.2x64/ ├── bin/ # postgis-3.dll、依赖 DLL、shp2pgsql 等命令行工具 ├── lib/ # 扩展的 .so/.dll 运行库 ├── share/ │ └── extension/ # postgis.control、postgis--3.4.2.sql 等扩展定义 └── utils/ # 一些辅助脚本这三个目录分别对应 PostgreSQL 安装目录下的bin、lib、share/extension。安装的本质就是「把 bundle 里的文件按对应关系复制过去」。理解这一点后面所有步骤都不会迷路。3. 在 Windows 上把 PostGIS 3.4.2 挂到 PG12复制、建扩展、验证三步走3.1 安装前必须确认的三件事动手之前先花两分钟确认环境能省掉后面一半的排错时间PostgreSQL 服务能正常启动用 pgAdmin 或psql能连上。PostgreSQL 安装目录可写因为你要往bin、lib、share/extension里复制文件。默认装在C:\Program Files\PostgreSQL\12的话复制时可能需要管理员权限。停掉 PostgreSQL 服务再复制 DLL。Windows 上正在运行的进程会锁住postgis-3.dll不停服务复制会提示文件被占用。停服务的命令管理员 PowerShell# 停止 PostgreSQL 12 服务服务名通常是 postgresql-x64-12 net stop postgresql-x64-12 # 复制完成后重新启动 net start postgresql-x64-12服务名不确定的话用services.msc打开服务列表找带 PostgreSQL 的那一项看它的「服务名称」列。3.2 按目录复制文件bin、lib、share/extension 各放什么假设 PostgreSQL 装在C:\Program Files\PostgreSQL\12bundle 解压在D:\postgis-bundle复制逻辑如下# 1. 复制 DLL 和命令行工具到 PG 的 bin 目录 # postgis-3.dll、libgeos、libproj、gdal 相关 DLL 都在这里 xcopy /Y /E D:\postgis-bundle\bin\* C:\Program Files\PostgreSQL\12\bin\ # 2. 复制运行库到 lib 目录 xcopy /Y /E D:\postgis-bundle\lib\* C:\Program Files\PostgreSQL\12\lib\ # 3. 复制扩展定义文件到 share\extension # 这一步最关键postgis.control 和 postgis--3.4.2.sql 都在这里 xcopy /Y /E D:\postgis-bundle\share\extension\* C:\Program Files\PostgreSQL\12\share\extension\xcopy的/Y表示覆盖时不询问/E表示连子目录一起复制。三条命令分别对应「可执行文件」「运行库」「扩展元数据」缺任何一条都会导致CREATE EXTENSION失败。复制完成后启动服务net start postgresql-x64-12注意如果你的 PostgreSQL 是通过 EDB 安装器装的share\extension目录里可能已经有一些其他扩展的 control 文件复制时不要删掉原有的只做覆盖和新增。3.3 建扩展并验证从 CREATE EXTENSION 到第一个空间查询服务起来后用 psql 或 pgAdmin 连上你要启用空间能力的数据库建议新建一个测试库别直接在生产库上试-- 连接到目标数据库后执行 CREATE EXTENSION postgis; -- 验证版本应该返回 3.4.2 相关字样 SELECT PostGIS_Full_Version(); -- 验证几何运算是否正常依赖 GEOS SELECT ST_Area(ST_Buffer(ST_Point(0,0), 1)); -- 验证投影转换是否正常依赖 PROJ SELECT ST_AsText(ST_Transform(ST_SetSRID(ST_Point(116.4, 39.9), 4326), 3857));PostGIS_Full_Version()会一次性输出 PostGIS、GEOS、PROJ、GDAL 的版本这是判断依赖有没有装全的最快方式。如果它返回了完整信息说明 bundle 里的依赖都被正确加载了。ST_Buffer测的是 GEOSST_Transform测的是 PROJ两个都通过基本可以确认安装成功。如果还想验证栅格能力GDAL可以再跑CREATE EXTENSION postgis_raster; SELECT ST_AsText(ST_Envelope(ST_MakeEmptyRaster(10, 10, 0, 0, 1, 1, 0, 0, 4326)));postgis_raster在 PostGIS 3.x 里是独立扩展需要单独创建但它依赖的 GDAL 库已经在 bundle 里了。4. postgis安装失败排查五类高频报错的现象、原因和解决4.1 报错 could not open extension control file现象执行CREATE EXTENSION postgis;时提示could not open extension control file .../share/extension/postgis.control: No such file or directory。原因share/extension目录里没有postgis.control说明第 3.2 步的第三条复制命令没执行或者复制到了错误的 PostgreSQL 目录比如机器上装了多个 PG 版本复制到了另一个版本下。解决确认当前连接的 PostgreSQL 用的是哪个安装目录。用SHOW data_directory;看数据目录反推安装目录然后把postgis.control和postgis--3.4.2.sql复制到正确的share/extension下。复制后不需要重启服务重新执行CREATE EXTENSION即可。4.2 报错 could not load library postgis-3.dll现象CREATE EXTENSION时报could not load library C:/Program Files/PostgreSQL/12/lib/postgis-3.dll: The specified module could not be found。原因这个报错有两层含义。一是postgis-3.dll本身没复制到lib目录二是 DLL 在但它依赖的 GEOS、PROJ、GDAL 等 DLL 不在bin目录Windows 加载时找不到依赖链。解决先确认lib\postgis-3.dll存在再确认bin目录下有geos.dll、proj.dll、gdal*.dll这类文件。bundle 的bin目录里通常有几十个 DLL全部复制过去不要只挑名字带 postgis 的。复制 DLL 前务必停服务否则文件被占用会复制失败但你可能没注意。4.3 报错 transform: couldnt project point现象CREATE EXTENSION成功了但一执行ST_Transform就报投影相关错误或者返回的坐标明显不对。原因PROJ 的数据文件proj.db 等没放对位置。PROJ 6 以后把投影参数从文本文件改成了 SQLite 数据库proj.db如果这个文件不在 PROJ 能找到的路径下投影转换就会失败。解决确认 bundle 的share目录下是否有proj子目录把它整体复制到 PostgreSQL 的share目录下。有些 bundle 会把 proj 数据放在share\contrib或直接share下按实际结构对应复制。复制后重启服务再测ST_Transform。4.4 报错 permission denied 或文件被占用现象复制 DLL 时提示Access is denied或另一个程序正在使用此文件。原因PostgreSQL 服务还在运行postgis-3.dll被 postgres 进程加载着Windows 不允许覆盖正在使用的 DLL。解决先net stop postgresql-x64-12确认服务真的停了任务管理器里没有 postgres.exe 进程再复制。如果停服务后还占用检查是不是有 pgAdmin 或其他客户端连着把它们也关掉。复制完再启动服务。4.5 报错版本不匹配或 extension postgis has no update path现象CREATE EXTENSION postgis;提示找不到匹配版本或者从旧版本升级时报没有升级路径。原因bundle 的版本和当前 PostgreSQL 大版本不匹配比如拿 pg12 的包往 PG14 上装或者数据库里已经装了旧版 PostGIS想直接覆盖但缺少升级脚本。解决先SELECT version();确认 PG 大版本再核对 bundle 文件名里的 pg 编号。如果是升级场景不要直接覆盖应该用ALTER EXTENSION postgis UPDATE;并确保share/extension里有对应的升级 SQL如postgis--3.3.0--3.4.2.sql。跨大版本升级 PostgreSQL 时PostGIS 也要跟着换对应 pg 版本的 bundle。5. 让这套环境真正好用批量部署脚本和版本升级的稳妥做法装通一次之后如果你要给团队多台机器部署或者以后要升级 PostGIS 小版本手动复制容易漏文件。我一般会写一个 PowerShell 脚本把复制逻辑固化下来参数化 PostgreSQL 路径和 bundle 路径param( [string]$PgRoot C:\Program Files\PostgreSQL\12, [string]$Bundle D:\postgis-bundle, [string]$ServiceName postgresql-x64-12 ) # 停服务避免 DLL 被占用 Stop-Service $ServiceName -Force # 按目录复制-Recurse 保证子目录一起过去 Copy-Item $Bundle\bin\* $PgRoot\bin\ -Recurse -Force Copy-Item $Bundle\lib\* $PgRoot\lib\ -Recurse -Force Copy-Item $Bundle\share\extension\* $PgRoot\share\extension\ -Recurse -Force # 如果 bundle 带 proj 数据一并复制 if (Test-Path $Bundle\share\proj) { Copy-Item $Bundle\share\proj\* $PgRoot\share\proj\ -Recurse -Force } Start-Service $ServiceName Write-Host PostGIS bundle 复制完成服务已重启这个脚本的关键点是Stop-Service -Force和-Recurse -Force。前者确保没有残留进程锁文件后者保证子目录和只读文件也能覆盖。参数化之后换 PG 版本或换机器只改三个变量。升级 PostGIS 小版本时稳妥顺序是先备份数据库pg_dump停服务用新 bundle 覆盖文件启动服务然后在每个已启用 PostGIS 的库里执行ALTER EXTENSION postgis UPDATE;和ALTER EXTENSION postgis_raster UPDATE;。不要跳过备份因为扩展升级偶尔会改系统表结构出问题回滚很麻烦。验证升级是否成功除了PostGIS_Full_Version()还可以查扩展版本SELECT extname, extversion FROM pg_extension WHERE extname LIKE postgis%;这条会列出 postgis、postgis_raster 等所有相关扩展的当前版本和 bundle 版本对得上就说明升级到位了。最后说个我自己的习惯每次装完 PostGIS我都会把PostGIS_Full_Version()的输出存一份到项目文档里标注清楚 PostgreSQL 版本、bundle 文件名、安装日期。因为过几个月再回来排查问题时你很难记得当时装的是 3.4.2 还是 3.4.1而版本差异往往就是玄学 bug 的根源。这套 bundle 方案在 Windows 上算是省心程度最高的做法把依赖一次性打包的思路值得记住。希望帮到你。本文还有配套的精品资源点击获取