无法将 PostgreSQL10 转储导入 9.6 数据库
Posted
技术标签:
【中文标题】无法将 PostgreSQL10 转储导入 9.6 数据库【英文标题】:Can't import PostgreSQL10 dump into 9.6 database 【发布时间】: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);
【问题讨论】:
【参考方案1】:从您显示的错误消息来看,您必须编辑 SQL 转储并从所有 CREATE SEQUENCE
语句中删除所有出现的 AS integer
。
CREATE SEQUENCE
的 AS <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' > test9.sql
你真的想在所有地方删除“作为整数”吗?我的目的是在“创建序列”发生后立即删除该行
我可以确认这个脚本也适用于将 PostgreSQL 11 降级到 9.6!感谢分享。
如果您正在处理 Rails db/structure.sql 文件,这里有一个 Ruby 脚本可以处理一些额外的不兼容性:gist.github.com/reedlaw/25e768d0cb853fc40bbdebfaeabaf360以上是关于无法将 PostgreSQL10 转储导入 9.6 数据库的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Mac OS 上使用自制软件将 postgresql 从 10.1 降级到 9.6 [关闭]
Docker-Compose Postgresql 导入转储
在Windows 10 x64中设置PostgreSQL 9.6(BigSQL图形安装程序)
将 PostgreSQL SQL 转储转换为 PostgreSQL 自定义格式转储