sqoop从hdfs导出到oracle错误

时间:2015-09-12 09:14:25

标签: oracle hdfs sqoop

使用的命令:

sqoop export --connect jdbc:oracle:thin:@//xxx:1521/BDWDEV4 --username xxx --password xxx --table TW5T0 --export-dir '/data/raw/oltp/cogen/oraclexport/TW5T0/2015-08-18' -m 8 --input-fields-terminated-by '\001' --lines-terminated-by '\n' --input-escaped-by '\"' --input-optionally-enclosed-by '\"'

目标表在oracle中包含数据类型为date的列但是错误地显示它将简单日期解析为时间戳

错误:

15/09/11 06:07:12 INFO mapreduce.Job:  map 0% reduce 0% 15/09/11 06:07:17 INFO mapreduce.Job: Task Id : attempt_1438142065989_99811_m_000000_0, Status : FAILED Error: java.io.IOException: Can't export data, please check failed map task logs
        at org.apache.sqoop.mapreduce.TextExportMapper.map(TextExportMapper.java:112)
        at org.apache.sqoop.mapreduce.TextExportMapper.map(TextExportMapper.java:39)
        at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:145)
        at org.apache.sqoop.mapreduce.AutoProgressMapper.run(AutoProgressMapper.java:64)
        at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:764)
        at org.apache.hadoop.mapred.MapTask.run(MapTask.java:340)
        at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:168)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:415)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1594)
        at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:163) Caused by: java.lang.RuntimeException: Can't parse input data: '2015-08-15'
        at TZ401.__loadFromFields(TZ401.java:792)
        at TZ401.parse(TZ401.java:645)
        at org.apache.sqoop.mapreduce.TextExportMapper.map(TextExportMapper.java:83)
        ... 10 more Caused by: java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
       at java.sql.Timestamp.valueOf(Timestamp.java:202)
        at TZ401.__loadFromFields(TZ401.java:709)
        ... 12 more

6 个答案:

答案 0 :(得分:1)

http://archive.cloudera.com/cdh/3/sqoop/SqoopUserGuide.html#_dates_and_times

  

Oracle JDBC将DATE和TIME SQL类型表示为TIMESTAMP值。 Oracle数据库中的任何DATE列都将作为SQoop中的TIMESTAMP导入,而Sqoop生成的代码将这些值存储在java.sql.Timestamp字段中。

     

将数据导出回数据库时,Sqoop将文本字段解析为   TIMESTAMP类型(格式为yyyy-mm-dd HH:MM:SS.ffffffff)即使   您希望使用JDBC日期转义格式化这些字段   格式为yyyy-mm-dd。导出到Oracle的日期应格式化为   全时间戳。

因此,在导出到Oracle之前,您需要格式化文件中的日期以符合格式yyyy-mm-dd HH:MM:SS.ffffffff

编辑:

回答评论,

  

我需要导出hdfs中的大约70个文件(表)。所以   文件我需要将日期从yyyy-mm-dd更改为yyyy-mm-dd   HH:MM:SS.ffffffff,任何简单的格式化方法。

那么你可以写一个awk脚本来为你做这件事。或者你可以检查以下想法是否有效:

  1. 创建一个新的临时表TEMPIMPORT,其结构与表TW5T0相同,只是将DATE数据类型的列更改为VARCHAR2
  2. 使用Sqoop加载到新临时表TEMPIMPORT
  3. 运行下面的DML将数据导回到int TW5T0(当然还有提交):

    从tempimport插入tw5t0(选择[[all_your_columns_here_except_date_column]],to_date(date_column,'yyyy-mm-dd');

答案 1 :(得分:1)

在export sqoop中使用了--connection-param-file ora.porperties

ora.properties包含 oracle.jdbc.mapDateToTimestamp =假

答案 2 :(得分:1)

您应该在sqoop导出中使用--map-column-java参数,而不是在Hadoop中更改数据文件。

如果您的Oracle表中有两个名为DATEDATE_COLUMN_1的{​​{1}}列,那么您可以将以下参数添加到sqoop命令中:

DATE_COLUMN_2

如前所述,必须在Hadoop文本文件中使用JDBC格式。但在这种情况下,--map-column-java DATE_COLUMN_1=java.sql.Date,DATE_COLUMN_2=java.sql.Date 将起作用。

答案 3 :(得分:0)

  

Oracle驱动程序将oracle.sql.DATE映射到java.sql.Timestamp,保留   时间信息。如果你仍然想要不正确但10g   兼容oracle.sql.DATE到java.sql.Date映射,然后就可以了   它通过将mapDateToTimestamp标志的值设置为false(默认值   是真的)。​​

https://docs.oracle.com/cd/E11882_01/java.112/e16548/apxref.htm#JJDBC28920

要与sqoop一起使用,您需要添加选项:

--connection-param-file conn-param-file.txt

CONN-PARAM-file.txt的:

oracle.jdbc.mapDateToTimestamp=false

答案 4 :(得分:0)

要与sqoop一起使用,您需要添加选项:

percentage = int(input("Please input a number")) if percentage == 100: grade = "A*" elif percentage == 80: grade = "A" elif percentage == 60: grade = "B" elif percentage == 40: grade = "C" else: grade = "D" print(grade)

CONN-PARAM-file.txt的:

--connection-param-file conn-param-file.txt

答案 5 :(得分:0)

如果Hive表列序列与RDBMS表列序列顺序不匹配,则存在相同错误的可能性。
我通过再次创建表重新排列RDBMS中的列后解决了我的问题。