【问题标题】:Can't import PostgreSQL10 dump into 9.6 database无法将 PostgreSQL10 转储导入 9.6 数据库
【发布时间】:2018-09-07 21:52:58
【问题描述】:

我需要以某种方式将 v10 转储文件转换为兼容 9.6 的文件

Google 的 Cloud SQL 运行 PostgreSQL 版本 9.6,而我的数据库自创建以来一直在版本 10 上运行。

问题:尝试将数据库导入 Cloud SQL 时,我收到 an unknown error has occurred. 死亡消息。

我已经尝试在导入 Cloud SQL 时注释掉我的 postgis /其他扩展,但无济于事。

我尝试使用 psql my_96_db < my_10.sql 并得到大量这样的错误:

...
CREATE TABLE
ERROR:  syntax error at or near "AS"
LINE 2:     AS integer
            ^
ERROR:  relation "authentication_phonecontact_id_seq" does not exist
CREATE TABLE
...

我尝试在我的 v10 pg_dump -Fc 命令上使用 postgres 9.6 的 pg_restore,但它无法成功导入 9.6 数据库。输出中的许多故障之一的示例是

pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.authentication_referral_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.authentication_referral_id_...
                                 ^
    Command was: SELECT pg_catalog.setval('public.authentication_referral_id_seq', 1, false);

【问题讨论】:

    标签: postgresql version google-cloud-sql


    【解决方案1】:

    从您显示的错误消息来看,您必须编辑 SQL 转储并从所有 CREATE SEQUENCE 语句中删除所有出现的 AS integer

    CREATE SEQUENCEAS <em>data_type</em> 子句是 PostgreSQL v10 中新增的,旧的服务器版本无法理解。

    【讨论】:

    • 为什么没有向后兼容转储的标志?
    • @grokpot 嗯?您不需要标志来转储较旧的 PostgreSQL 服务器。并且您不允许转储更高版本的 PostgreSQL 服务器。那很好,因为 9.4 服务器应该如何知道如何正确转储 v10 数据库?
    • @LaurenzAlbe v10 应该知道如何转储 v9.x 兼容的备份恕我直言
    • @Mirko 它应该如何转储旧版本中不存在的东西?只是默默地放下它们?出错了?无论如何,您永远不必降级,因此没有人有足够的动力为此编写支持。这很难,而且会使 pg_dump 更加复杂。
    • 只是为了记录,这也适用于将转储从 postgresql 10 反向移植到 portgresql 9.5
    【解决方案2】:

    根据@"Laurenz Albe" 的建议,这里有一个 python3 sn-p 可用于为 9.x 降级 10.x pg_dump 脚本:

    #!/usr/bin/env python3
    import sys
    
    #
    #  Downgrades pg_dump 10 script to 9.x
    #  removing 'AS integer' from 'CREATE SEQUENCE' statement
    #
    #  Usage:
    #       $ python3 pgdump_10_to_9.py < test10.sql > test9.sql
    #  or:
    #       $ cat test10.sql | ./pgdump_10_to_9.py > test9.sql
    #
    #  To obtain a compressed 9.x sql script from a compressed 10 sql script:
    #
    #       $ gunzip -c test10.sql.gz | ./pgdump_10_to_9.py | gzip > test9.sql.gz
    #
    
    inside_create_sequence = False
    for row in sys.stdin.readlines():
    
        if inside_create_sequence and row.strip().lower() == 'as integer':
            pass
        else:
            print(row, end='', flush=True)
    
        inside_create_sequence = row.strip().startswith('CREATE SEQUENCE ')
    

    【讨论】:

    • 感谢您编写此脚本。它使转换文件变得超级容易。
    • 一个不太复杂的解决方案是使用sed,cat test10.sql | sed '/AS integer/d' &gt; test9.sql
    • 你真的想在所有地方删除“作为整数”吗?我的目的是在“创建序列”发生后立即删除该行
    • 我可以确认这个脚本也适用于将 PostgreSQL 11 降级到 9.6!感谢分享。
    • 如果您正在处理 Rails db/structure.sql 文件,这里有一个 Ruby 脚本可以处理一些额外的不兼容性:gist.github.com/reedlaw/25e768d0cb853fc40bbdebfaeabaf360
    猜你喜欢
    • 2015-05-16
    • 2010-09-23
    • 2011-07-22
    • 1970-01-01
    • 1970-01-01
    • 2016-07-31
    • 1970-01-01
    • 2022-12-12
    相关资源
    最近更新 更多