pg_dump导出Redshift表报错‘ONLY relation’不支持,寻求技术帮助
解决Redshift中pg_dump报错"ONLY relation is not supported"的问题
错误原因分析
你遇到的这个报错是因为标准PostgreSQL的pg_dump工具在导出表时,会默认生成带有ONLY关键字的查询(比如SELECT * FROM ONLY archive_table_test)——这个关键字是PostgreSQL用来处理表继承特性的,但Redshift完全移除了表继承的支持,自然无法识别ONLY语法。再加上你使用的PostgreSQL 8.0.2版本非常老旧,和Redshift 1.0.2369的兼容性本来就很差,才会出现这个罕见的报错。
解决方案
下面提供几种可行的方法,帮你生成包含INSERT语句的SQL文件:
方法1:调整pg_dump参数,绕过ONLY关键字
尝试给pg_dump命令加上明确的schema指定(比如你的表在public schema下),同时添加--no-security-labels和--no-tablespaces参数(这些参数能减少pg_dump生成Redshift不兼容的语法):
pg_dump -h xxx -p xxx -d xxx -U xxx -W --table=public.archive_table_test --column-inserts --no-security-labels --no-tablespaces > ~/dumps/test_dump_5_31.sql
如果这个方法依然报错,就试试下面的分步导出方案。
方法2:分步导出表结构+数据,手动生成INSERT语句
这个方法更可靠,适合所有Redshift版本:
- 导出表结构:用pg_dump只导出表的创建语句,不包含数据:
pg_dump -h xxx -p xxx -d xxx -U xxx -W --table=archive_table_test --schema-only > ~/dumps/test_dump_schema.sql - 导出表数据为CSV:用psql的
\copy命令直接从Redshift导出数据:
先连接到Redshift:
执行导出命令:psql -h xxx -p xxx -d xxx -U xxx -W\copy (SELECT * FROM archive_table_test) TO '~/dumps/test_dump_data.csv' WITH CSV HEADER - 将CSV转换为INSERT语句:用简单的Python脚本处理CSV,生成标准INSERT语句:
import csv import os table_name = "archive_table_test" input_csv = os.path.expanduser("~/dumps/test_dump_data.csv") output_sql = os.path.expanduser("~/dumps/test_dump_inserts.sql") with open(input_csv, 'r', encoding='utf-8') as csv_file: reader = csv.reader(csv_file) headers = next(reader) column_list = ", ".join(headers) with open(output_sql, 'w', encoding='utf-8') as sql_file: sql_file.write(f"INSERT INTO {table_name} ({column_list}) VALUES\n") row_strings = [] for row in reader: # 处理字符串转义(单引号替换为两个单引号) escaped_cells = [] for cell in row: if cell is None or cell == '': escaped_cells.append('NULL') elif isinstance(cell, str): escaped_cells.append(f"'{cell.replace('''', '''''')}'") else: escaped_cells.append(str(cell)) row_strings.append(f"({', '.join(escaped_cells)})") sql_file.write(',\n'.join(row_strings) + ';\n') - 合并文件:把结构文件和INSERT语句文件合并成最终的SQL文件:
cat ~/dumps/test_dump_schema.sql ~/dumps/test_dump_inserts.sql > ~/dumps/final_dump.sql
方法3:针对大数据量的UNLOAD方案
如果你的表数据量很大,\copy效率会很低,可以用Redshift原生的UNLOAD命令把数据导出到S3,再下载转换为INSERT语句:
- 执行UNLOAD命令(需要配置好S3权限):
UNLOAD ('SELECT * FROM archive_table_test') TO 's3://your-bucket-name/dumps/test_dump_' IAM_ROLE 'arn:aws:iam::your-account-id:role/your-redshift-unload-role' FORMAT CSV HEADER DELIMITER ',' QUOTE '"'; - 下载S3上的CSV文件,再用方法2中的Python脚本转换成INSERT语句即可。
额外提醒
Redshift本身是为大数据量设计的,INSERT语句导入数据的效率极低。如果你的最终目的是迁移数据,优先考虑用UNLOAD+COPY的组合(Redshift原生的高效数据迁移方式),只有在必须要SQL格式的INSERT语句时,再使用上面的方法。
内容的提问来源于stack exchange,提问作者aggis
相关产品推荐
相关产品推荐

