由于 RDS(Oracle) 不直接支持 SSH,FTP(基于安全因素吧). 所以原有系统 expdp 或 exp 出来的 dmp 文件, 不能直接导入到 RDS 中官方文档里建议通过 networklink 或者 dblink 的方式 从原有数据库迁移到 RDS, 考虑到网络和安全因素, 此方法暂被忽略掉
查找各种文档发现, 可以通过 Oracle 自身的 UTL_FILE 包来写 dmp 文件到 RDS 的文件夹里, 读取 EC2 里的本地文件部分通过 Python 脚本实现, 这样变相实现了, 从 EC2 本地上传到 RDS 的功能
代码如下:
- def cpy_to_rds():
- file_name = 'test4.dmp'
- src_name = 'c:/testdata/test4.dmp'
- #在 RDS,DATA_PUMP_DIR 下新建或者覆盖一个空文件
- UTL_FILE_NEW_FILE = "DECLARE fi UTL_FILE.FILE_TYPE; BEGIN fi:=UTL_FILE.fopen('DATA_PUMP_DIR','{0}','wb',32766); UTL_FILE.fclose(fi); END;"
- #写入 RDS
- UTL_FILE_CREATE_FILE = "DECLARE" \
- "fi UTL_FILE.FILE_TYPE;" \
- "v_buffer RAW(32760);" \
- "BEGIN" \
- "v_buffer:= hextoraw('{1}') ;" \
- "fi:=UTL_FILE.fopen('DATA_PUMP_DIR','{0}','ab');" \
- "UTL_FILE.put_raw(fi,v_buffer);" \
- "UTL_FILE.fclose(fi);" \
- "END;"
- con = cx_Oracle.connect('User/Password@SID')
- cur = con.cursor()
- # 在 RDS,DATA_PUMP_DIR 下新建或者覆盖一个空文件
- cur.execute(UTL_FILE_NEW_FILE.format(file_name))
- chunk = 3000
- f = open(src_name, 'rb')
- line = f.read(chunk)
- # 写入 RDS
- cur.execute(UTL_FILE_CREATE_FILE.format(file_name, line.hex()))
- while (len(line))> 0:
- line = f.read(chunk)
- # 写入 RDS
- cur.execute(UTL_FILE_CREATE_FILE.format(file_name, line.hex()))
- cur.close()
- con.close()
需要注意的是 chunk 设置不能为 32760
UTL_FILE_CREATE_FILE 语句也可以转换为 RDS 中的一个 Function 函数:
- create or replace function gen_dmp(i_name IN VARCHAR2, i_buffer IN RAW ) return varchar2 is
- begin
- declare
- v_file utl_file.file_type;
- begin
- v_file:=utl_file.fopen('DATA_PUMP_DIR',i_name,'ab');
- utl_file.put_raw(v_file,i_buffer);
- utl_file.fclose(v_file);
- return 'OK';
- end;
- end;
在 Python 中调用此函数, 这样 chunk 就可以设置到 32767 最大值了.
- def cpy_to_rds_func():
- file_name = 'tes4.dmp'
- src_name = 'c:/testdata/test4.dmp'
- UTL_FILE_NEW_FILE = "DECLARE fi UTL_FILE.FILE_TYPE; BEGIN fi:=UTL_FILE.fopen('DATA_PUMP_DIR','{0}','wb',32766); UTL_FILE.fclose(fi); END;"
- con = cx_Oracle.connect('User/Password@SID')
- cur = con.cursor()
- cur.execute(UTL_FILE_NEW_FILE.format(file_name))
- chunk = 32760
- f = open(src_name, 'rb')
- line = f.read(chunk)
- cur.callfunc('gen_dmp', cx_Oracle.STRING, (file_name, line))
- while (len(line))> 0:
- line = f.read(chunk)
- cur.callfunc('gen_dmp', cx_Oracle.STRING, (file_name, line))
- cur.close()
- con.close()
来源: http://www.linuxidc.com/Linux/2018-03/151365.htm