如何为shema_1和shema_2两个Schema安装PostGIS扩展?
多Schema下PostGIS扩展的配置方案
问题根源
PostGIS是数据库级扩展,同一数据库内只能安装一次。你执行CREATE EXTENSION时,因为搜索路径首项是schema_1(注意你拼写的shema是笔误,应为schema),所以扩展对象默认创建在该schema下,重复执行CREATE EXTENSION到其他schema自然会提示已存在。
具体解决步骤
1. 确认PostGIS基础安装
先确保PostGIS已安装到其中一个schema(比如schema_1),如果还没完成,执行:
CREATE SCHEMA IF NOT EXISTS schema_1 AUTHORIZATION admin; CREATE EXTENSION IF NOT EXISTS postgis WITH SCHEMA schema_1;
2. 让schema_2能访问PostGIS对象(两种可选方案)
方案一:权限授权+搜索路径(推荐,无需复制对象)
适合PostgreSQL 12+版本,只需给目标schema用户授权访问PostGIS所在schema,再调整搜索路径:
-- 创建schema_2(若未创建) CREATE SCHEMA IF NOT EXISTS schema_2 AUTHORIZATION admin; -- 授权admin用户访问schema_1的PostGIS对象 GRANT USAGE ON SCHEMA schema_1 TO admin; -- 永久设置admin用户的搜索路径 ALTER ROLE admin SET search_path = schema_1, schema_2, public;
方案二:复制PostGIS对象到schema_2
如果必须让PostGIS对象存在于schema_2中,可以复制函数、类型等对象(注意:后续PostGIS升级时需重新同步):
-- 复制ST_开头的PostGIS函数到schema_2 DO $$ DECLARE rec record; BEGIN FOR rec IN SELECT proname, oid FROM pg_proc WHERE pronamespace = 'schema_1'::regnamespace AND proname LIKE 'ST_%' LOOP EXECUTE 'CREATE OR REPLACE FUNCTION schema_2.' || rec.proname || '(' || pg_get_function_arguments(rec.oid) || ') ' || pg_get_function_result(rec.oid) || ' AS ' || quote_literal(pg_get_functiondef(rec.oid)) || ' LANGUAGE sql STABLE;'; END LOOP; END $$; -- 复制PostGIS核心类型到schema_2 DO $$ DECLARE rec record; BEGIN FOR rec IN SELECT typname FROM pg_type WHERE typnamespace = 'schema_1'::regnamespace AND typname IN ('geometry', 'geography', 'geometry_dump') LOOP EXECUTE 'CREATE TYPE schema_2.' || rec.typname || ' AS (' || pg_get_type_def(rec.oid) || ');'; END LOOP; END $$;
3. Django适配配置
在settings.py中,除了ORIGINAL_BACKEND,还需配置数据库搜索路径,确保Django能识别多schema的PostGIS对象:
DATABASES = { 'default': { 'ENGINE': 'django.contrib.gis.db.backends.postgis', 'NAME': '你的数据库名', 'USER': 'admin', 'PASSWORD': '你的密码', 'HOST': 'localhost', 'PORT': '5432', 'OPTIONS': { 'options': '-c search_path=schema_1,schema_2,public' }, } }
内容的提问来源于stack exchange,提问作者Kirill
相关产品推荐
相关产品推荐

