Sqoop--direct模式导入PostgreSQL含换行字段到Hive拆行问题求解
Sqoop PostgreSQL direct导入字段含换行的解决方案
注意:Sqoop的
--input-escaped-by、--hive-delims-replacement等参数仅作用于Sqoop自身的解析逻辑,direct模式下数据导出完全由PostgreSQL的COPY命令处理,所以这些参数不会生效。
方案1:修改Hive表使用CSVSerDe解析带引号的换行字段
该方案无需调整导入流程,仅修改Hive表配置即可识别Sqoop direct生成的带引号包裹换行的CSV文件:
- 创建/修改Hive表时指定使用
org.apache.hadoop.hive.serde2.OpenCSVSerde - 配置SerDe参数匹配Sqoop生成的文件格式:分隔符为逗号、引号为双引号
示例建表语句:
CREATE TABLE your_table ( col1 string, col2 string, col3 string ) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' WITH SERDEPROPERTIES ( "separatorChar" = ",", "quoteChar" = "\"", "escapeChar" = "\\" ) STORED AS TEXTFILE;
配置完成后直接执行LOAD DATA INPATH即可正确识别引号内的换行,不会拆分单条记录。
方案2:在Sqoop导入阶段使用COPY原生参数处理换行
Sqoop direct模式支持在命令末尾加--传递PostgreSQL COPY命令的原生参数,直接在导出阶段处理字段内的换行:
- 方法A:指定COPY转义规则,将字段内换行转义,示例Sqoop命令:
sqoop import \ --connect jdbc:postgresql://pg_host:port/db_name \ --username xxx --password xxx \ --table your_pg_table \ --direct \ --target-dir /path/to/hdfs_save \ -- \ --escape '\' --newline '\\n'
- 方法B:在查询层替换换行,搭配
--query参数调用PostgreSQL的replace函数直接替换字段内的换行符,示例:
sqoop import \ --connect jdbc:postgresql://pg_host:port/db_name \ --username xxx --password xxx \ --direct \ --query "SELECT col1, replace(col2, E'\n', ' ') as col2, col3 FROM your_pg_table WHERE \$CONDITIONS" \ --target-dir /path/to/hdfs_save \ --split-by col1
方案3:导入后预处理HDFS文件再加载到Hive
如果不方便修改导入命令和Hive表结构,可以编写简单的Spark/Python脚本遍历生成的HDFS文件,将双引号包裹的换行符替换为空格或者转义符,处理完成后再执行LOAD操作,该方案兼容性最高,无需调整现有流程的核心配置。
内容的提问来源于stack exchange,提问作者kumar
相关产品推荐
相关产品推荐

