Amazon RDS中PostGIS扩展存在但geometry类型不存在的Rails问题
问题分析与解决方案
问题现象
在Amazon RDS的PostgreSQL实例中使用PostGIS时,出现以下异常:
- PostGIS扩展已安装,空间数据可正常写入(如执行
record.update(lonlat: 'POINT(2.4214133 48.7364525)')返回true)和读取(record.lonlat返回RGeo对象) - 执行空间查询语句
Records.where("ST_DWithin(records.lonlat, 'POINT(-1.548977 47.216369)'::GEOMETRY, '10000'::INTEGER)")时,报错ActiveRecord::StatementInvalid (PG::UndefinedObject: ERROR: type "geometry" does not exist) - 尝试删除重建PostGIS扩展时,因存在依赖对象失败:
ActiveRecord::StatementInvalid (PG::DependentObjectsStillExist: ERROR: cannot drop extension postgis because other objects depend on it) - PostGIS部署在独立schema中,该schema已加入搜索路径且已授予全部权限,本地及Heroku环境无此问题
- 使用
activerecord-postgis-adaptergem,PostGIS版本为3.1 USE_GEOS=1 USE_PROJ=1 USE_STATS=1,database.yml中URL配置为url: <%= ENV.fetch('DATABASE_URL', '').sub(/^postgres(ql)?/, "postgis") %>
可能的解决方案
1. 显式指定Geometry类型的Schema
由于PostGIS安装在独立Schema中,查询时需明确指定类型所属的Schema,避免数据库无法找到geometry类型:
将查询语句修改为:
Records.where("ST_DWithin(records.lonlat, 'POINT(-1.548977 47.216369)'::your_postgis_schema.geometry, 10000)")
(将your_postgis_schema替换为实际的PostGIS所在Schema名称)
2. 确认数据库连接的搜索路径配置
虽然已将PostGIS Schema加入搜索路径,但需确保连接会话的搜索路径生效:
- 在database.yml中显式指定
schema_search_path:
production: url: <%= ENV.fetch('DATABASE_URL', '').sub(/^postgres(ql)?/, "postgis") %> schema_search_path: "public,your_postgis_schema"
- 执行SQL语句验证搜索路径:
SHOW search_path;
确保结果包含PostGIS所在的Schema。
3. 检查activerecord-postgis-adapter的连接配置
确认database.yml中已正确指定PostGIS适配器,避免连接时未加载PostGIS相关类型:
production: adapter: postgis url: <%= ENV.fetch('DATABASE_URL', '').sub(/^postgres(ql)?/, "postgis") %> schema_search_path: "public,your_postgis_schema"
4. 验证PostGIS扩展的安装状态
执行以下SQL确认PostGIS扩展的安装位置及依赖:
-- 查看PostGIS所在Schema SELECT nspname FROM pg_extension e JOIN pg_namespace n ON e.extnamespace = n.oid WHERE e.extname = 'postgis'; -- 查看依赖PostGIS的对象 SELECT * FROM pg_depend WHERE refobjid = (SELECT oid FROM pg_extension WHERE extname = 'postgis');
若依赖对象为业务表,可先备份数据后删除相关表,再尝试重建扩展(仅在必要时操作)。
内容的提问来源于stack exchange,提问作者Thib
相关产品推荐
相关产品推荐

