用Sqoop从oracle导出到Hive中的ORC table

本文介绍了如何通过cx_Oracle获取表结构,利用Pandas和Spark JDBC快速创建小规模DataFrame,然后将数据转换为ORC格式并导入Hive内表,省去了手动建表步骤,适用于大规模数据迁移。

之前尝试的都是用sqoop导出到hive中的hdfs里,作为外部表。再到hive里建内部表,关联上外部表。

这次尝试直接用sqoop将oracle数据(千万量级)导出到hive中的内部表里。

全程不需要手动建表,方法如下:

1. 利用cx_Oracle程序从oracle里读取表格的前几行数据,读成pandas dataframe。

2. 利用pyspark程序从oracle里用spark.read.jdbc读取原始表,返回值为pyspark dataframe。

3. 利用pyspark的schema和pandas的几行dataframe,组合成一个只有几行的新的pyspark的dataframe,这样做的好处是避免step2中读出来的大表,需要很长时间才能加载进内容中。

4. 将Step3中的小小pyspark dataframe,写入到hive中,指定格式为ORC:

pydf.write.option('orc.compress', 'snappy').mode('overwrite').saveAsTable(tbl_name, format='hive')

5. 到hadoop-master中,编写sqoop脚本抽取数据。从Sqoop 1.4.4开始,Sqoop集成了HCatalog,可以支持导入为ORC格式的表格。但是需要配置HCAT_HOME的环境变量,本人是在容器中操作,所以环境变量为:

export HCAT_HOME=/usr/local/hive/hcatalog

先验证一下sqoop,运行sqoop-version,如果弹出很多报警信息,需要修改/usr/local/sqoop/bin/configure-sqoop,注释掉一些语句,这里请自行网上查询不再细说。

运行成功如图:

运行脚本如下:

每次运行之前先清理一下表。否则会追加。 

 

<think> 嗯,用户正在询问如何将Oracle数据库迁移到Hive的方法。这个问题涉及跨数据库的数据迁移,需要综合考虑权限、数据映射和同步机制。 用户可能正在处理数据仓库迁移项目,从引用内容看有几个关键痛点:没有Oracle服务器权限、源表结构存在历史遗留字段、目标Hive表需要新的数据结构。这暗示着实际场景可能是企业级数据平台迁移,用户大概率是数据工程师或ETL开发人员。 需要特别注意两个技术难点:第一是权限受限情况下的数据抽取方案,引用[2]提到的sqluldr2工具很实用,它支持并行查询导出且无需服务器权限;第二是字段映射问题,Oracle的"添加不删字段"策略导致表结构臃肿,而Hive需要精简结构,这要求设计智能字段转换逻辑。 考虑到用户没提实时同步需求,先聚焦历史数据迁移。核心步骤应该是:1)用外部工具绕过权限限制抽取数据;2)建立字段映射规则处理结构差异;3)设计HDFS落地策略;4)处理数据类型转换。对于增量同步部分,虽然用户当前没问,但作为完整方案应该提及CDC或时间戳两种常见方案。 用户引用中提到的字段对应问题值得深入。Oracle的varchar2(4000)直接转Hive string可能浪费存储,需要考虑长度优化;而DATE类型处理也要注意时区问题。在Hive表设计时建议采用ORC格式并分区,这对后续查询性能很关键。 突然想到个潜在风险:如果Oracle表包含CLOB大字段,csv导出可能截断数据,需要提醒用户检查大字段处理方案。另外迁移后的数据校验也很重要,可以补充count(*)/hashsum验证方法。 </think>以下是将Oracle数据库迁移到Hive的完整方案及注意事项,结合技术实现与最佳实践: --- ### **迁移步骤** #### 1. **数据抽取** - **工具选择**: - ✅ **SQLULDR2**:无需DB权限,直接通过SQL查询导出(引用[2]示例): ```bash sqluldr2.bin user=user/pwd@tnsname query="SELECT /*+ parallel(8) */ * FROM table" head=no file=/path/output.csv ``` - 📌 **Sqoop**(需JDBC连接权限): ```bash sqoop import --connect jdbc:oracle:thin:@//host:port/sid \ --username user --password pwd \ --table tablename --target-dir /hdfs/path \ --fields-terminated-by ',' --null-string '\\N' ``` #### 2. **字段映射与清洗** - **核心问题**:Oracle表存在历史遗留字段,Hive需新结构(引用[1]) - **解决方案**: 1. 创建Hive目标表(仅需有效字段): ```sql CREATE TABLE hive_table ( id INT, valid_field1 STRING, -- 仅保留必要字段 valid_field2 TIMESTAMP ) STORED AS ORC; ``` 2. 编写字段转换脚本(Python示例): ```python # 读取Oracle导出的CSV,按新结构映射 with open('oracle_export.csv') as f_in, open('hive_ready.csv','w') as f_out: for line in f_in: cols = line.split(',') # 按新结构选择列:col0, col2, col5 (丢弃无效字段) f_out.write(f"{cols[0]},{cols[2]},{cols[5]}\n") ``` #### 3. **数据加载到Hive** - **直接加载清洗后文件**: ```sql LOAD DATA LOCAL INPATH '/path/hive_ready.csv' OVERWRITE INTO TABLE hive_table; ``` - **使用Hive外部表**(避免重复拷贝): ```sql CREATE EXTERNAL TABLE hive_external ( id INT, valid_field1 STRING ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION '/hdfs/path/cleaned_data/'; ``` #### 4. **增量同步方案** - **基于时间戳**(Oracle需有更新时间字段): ```sql -- Sqoop增量导入 sqoop import --incremental lastmodified \ --check-column update_time --last-value "2023-01-01" ... ``` - **CDC工具**(高实时性场景): - Debezium + Kafka → Hive Connector - Oracle GoldenGate → HDFS --- ### **关键注意事项** 1. **权限规避技巧** - 无权限时优先用SQLULDR2导出CSV(引用[2]) - 导出后通过SCP/SFTP传输至Hadoop集群 2. **字段对齐策略** - 使用**字段位置映射**而非名称匹配(因Oracle存在冗余字段) - 缺失字段处理:Hive中`NULL`补位,避免列数不一致报错 3. **性能优化** - Oracle侧:`/*+ parallel(N) */` 提升查询并发度 - Hive侧:ORC格式 + Snappy压缩,提升查询效率 ```sql CREATE TABLE optimized_table STORED AS ORC TBLPROPERTIES ("orc.compress"="SNAPPY") AS ... ``` 4. **数据类型转换** | Oracle类型 | Hive类型 | 处理方案 | |----------------|---------------|------------------------| | VARCHAR2(4000) | STRING | 直接转换 | | DATE | TIMESTAMP | 格式化为ISO标准(YYYY-MM-DD HH:MI:SS)| | NUMBER(10) | INT | 注意精度溢出 | --- ### **常见问题解决方案** - **问题1:Oracle大表导出超时** **方案**:分批次导出(按主键分段) ```sql SELECT * FROM table WHERE id BETWEEN 1 AND 100000 ``` - **问题2:Hive表中文乱码** **方案**:导出时指定编码`NLS_LANG=AMERICAN_AMERICA.AL32UTF8` - **问题3:增量数据合并** **方案**:Hive ACID事务表(需Hive 3+) ```sql MERGE INTO hive_target AS T USING incremental_data AS S ON T.id = S.id WHEN MATCHED THEN UPDATE SET ... WHEN NOT MATCHED THEN INSERT ... ``` --- ### **引用验证** > 现有Oracle数据库在使用无法整个库导出数据库服务器没有权限... oracle数据库采取添加字段而不删除字段的方式更新,而hive中建立的表数据结构要按新的来[^1]。 > sqluldr2.bin user=root/pwd@tnsname query="select /*+ parallel(8) */ * from table" head=no File=/data/oracle/tmp/file[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值