You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL如何从外部服务器迁移所有枚举类型

PostgreSQL跨库迁移含枚举类型Schema的解决方案

核心原因是PostgreSQL外部表要求源库和目标库的同名字段枚举类型的OID、枚举值顺序完全匹配,否则创建外部表时会抛出SQL错误。你可以通过以下两种方式批量导出源库的所有枚举类型,先同步到目标库再进行后续的 schema 迁移操作。

方式1:使用pg_dump过滤导出枚举定义

pg_dump 没有专门导出枚举类型的参数,但可以通过导出全量 schema 结构后过滤枚举相关DDL的方式实现,命令如下:

pg_dump -h [源库地址] -U [用户名] -d [源库名] --schema-only | grep -A 1 -B 1 'ENUM' > enums.sql

如果需要只导出指定schema的枚举,可以给pg_dump加上-n [schema名]参数缩小范围。

方式2:查询系统表生成精准的枚举DDL

如果担心过滤方式遗漏枚举的权限设置、枚举值顺序问题,可以直接在源库执行如下SQL,自动生成所有枚举类型的创建语句:

WITH enum_types AS (
    SELECT 
        t.oid,
        n.nspname AS schema_name,
        t.typname AS enum_name
    FROM pg_type t
    JOIN pg_namespace n ON t.typnamespace = n.oid
    WHERE t.typtype = 'e'
    -- 取消注释并替换为目标schema可过滤指定schema的枚举
    -- AND n.nspname = 'your_schema_name'
)
SELECT 
    'CREATE TYPE ' || quote_ident(schema_name) || '.' || quote_ident(enum_name) || ' AS ENUM (' ||
    string_agg(quote_literal(e.enumlabel), ', ' ORDER BY e.enumsortorder) || ');' AS enum_ddl
FROM enum_types t
JOIN pg_enum e ON t.oid = e.enumtypid
GROUP BY t.oid, schema_name, enum_name
UNION ALL
-- 可选:生成枚举类型的权限授权语句
SELECT 
    'GRANT USAGE ON TYPE ' || quote_ident(n.nspname) || '.' || quote_ident(t.typname) || 
    ' TO ' || quote_ident(r.rolname) || ';'
FROM pg_type t
JOIN pg_namespace n ON t.typnamespace = n.oid
JOIN pg_acl acl ON acl.aclowner = t.typowner
JOIN pg_roles r ON acl.acl_grantee = r.oid
WHERE t.typtype = 'e' AND acl.acl_grantee <> 0;

将上述SQL的执行结果保存为enums.sql文件即可。

导入到目标库

  1. 先在目标库创建对应schema(如果不存在):
CREATE SCHEMA IF NOT EXISTS [你的schema名];
  1. 执行枚举SQL文件导入所有枚举类型:
psql -h [目标库地址] -U [用户名] -d [目标库名] -f enums.sql

后续操作

枚举类型完全同步到目标库后,再创建外部表或导入完整schema的数据,即可避免枚举类型不匹配的报错。
注意:如果后续源库的枚举值有新增/调整,需要先同步目标库的枚举定义,再同步对应数据。

内容的提问来源于stack exchange,提问作者Peter Mølgaard Pallesen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 12:39:02