Ora2Pg:将Oracle迁移到PostgreSQL的免费工具


Ora2Pg是一个免费工具,用于将Oracle或MySQL数据库迁移到PostgreSQL兼容模式。它连接Oracle数据库,自动对其进行扫描并提取其结构或数据,然后生成可加载到PostgreSQL数据库中的SQL脚本。
Ora2Pg可以用于从反向工程Oracle数据库到大型企业数据库的迁移,也可以用于将一些Oracle数据复制到PostgreSQL数据库中。除了提供连接到Oracle数据库所需的参数外,它确实非常易于使用,并且不需要任何Oracle数据库知识。
功能包括

  • 导出具有唯一,主,外键和检查约束的完整数据库架构(表,视图,序列,索引)。
  • 导出用户和组的授予/特权。
  • 导出范围/列表分区和子分区。
  • 导出表选择(通过指定表名称)。
  • 将Oracle模式导出到PostgreSQL 8.4+模式。
  • 导出预定义的函数,触发器,过程,程序包和程序包主体。
  • 导出完整数据或遵循WHERE子句。
  • 完全支持将Oracle BLOB对象作为PG BYTEA。
  • 将Oracle视图导出为PG表。
  • 导出Oracle用户定义的类型。
  • 提供从PLSQL代码到PLPGSQL的一些基本的自动转换。
  • 适用于任何平台。
  • 将Oracle表导出为外部数据包装器表。
  • 导出物化视图。
  • 显示有关Oracle数据库内容的详细报告。
  • Oracle数据库的迁移成本评估。
  • Oracle数据库的迁移难度级别评估。
  • 文件中PL / SQL代码的迁移成本评估。
  • 存储在文件中的Oracle SQL查询的迁移成本评估。
  • 生成要与Penthalo Data Integrator(Kettle)一起使用的XML ktr文件
  • 将Oracle定位器和空间几何导出到PostGis。
  • 将DBLINK导出为Oracle FDW。
  • 将SYNONYMS导出为视图。
  • 将DIRECTORY导出为ex​​ternal_file扩展名的外部表或目录。
  • 完全MySQL导出,就像Oracle数据库一样。

 
HN讨论
我已经使用它来迁移一些应用程序。它工作得很好。此外,“ orafce”扩展名还有助于减少对应用程序进行的实际SQL查询的必要更改。
在我的情况下,应用程序相对简单,但是许多查询显式地使用了序列,并且缺乏通用语法,这有一点痛苦。
 
Oracle实际上提供了一个出色的数据库产品,它具有非常好的复制/故障转移功能和非常好的性能。这不是一个不好的数据库,并且扩展性非常好。与您可能获得的任何好处相比,Oracle数据库许可证的价格简直太高了。
 
Oracle或Microsoft RDBMS的许可成本与其所支持的项目成本相比微不足道,而且很容易找到价值所在。这些公司提供的功能和管理工具使大规模运行RDBMS的所有困难(群集,故障转移/复制,统计信息收集,计划管理,监视,在线索引重建,表分区...)都变得容易。为此添加真正的体面支持,您将获得非常明确的价值主张。
Postgres实例将需要更多的管理经验,并且需要对数据库引擎的工作方式有更深入的了解。在较小的规模上,这些因素不太可能引起问题,并且许多组织不太可能真正达到大规模(许多TB实例,每秒运行数百或数千个事务)。但是,如果要开始扩展RDBMS应用程序,则将不得不以一种或另一种方式来应对这些成本。在此之后,许可昂贵的功能可能比部署更多的专业劳动力看起来更好。
 
最近,我们使用Org2Pg将我们的Oracle数据库(已经使用了15年)移动到Postgres。即使使用Ora2Pg,我们也花了2年的时间。
  1.  Ora2Pg将创建一个文件,其中包含Postgres格式的所有表,列,索引,键等。不幸的是,这很不错,但是我们发现我们必须进行大量的手动调整才能使其真正可用。例如,它确实是选择正确的数据类型的最佳猜测,但是我们不同意它的所有选择,因此我们必须仔细检查每个选择并确定需要更改的数据。另外,在Oracle和Postgres上设置主键的方式也大不相同Ora2Pg采用字面翻译来翻译如何设置Oracle主键,而不是使用Postgres方式-因此我们必须修复所有这些。
  2. 它不能真正转换函数和触发器。所有这些都必须手工重写。
  3. 要花费大量时间进行调整和实验,才能使Ora2Pg在相当长的时间内传输数据。我们的第一次尝试听了将近24声。我们最终将其调整到大约一个小时。
  4. 您仍然需要将所有SQL查询重写为Postgres格式。这是花费时间最多的部分,因为我们有大约5,000个查询,并且每个查询都必须进行检查。
  5. 最大的痛苦是,在数据库迁移正在进行的过程中,我们无法停止开发。因此,每次对Oracle数据库进行更改时,我们都必须手动对Postgres DDL文件进行相同的更改。

叹。我很高兴这个项目在我身后。我再也不想参与类似的事情了。这是完全值得的(与Oracle相比,Postgres是一个与之合作的梦想),但是过程却是一场噩梦。
有关将查询从Oracle转换为Postgres的一些说明:
  • 在Postgres中,“ foo IN(a,b,c)”通常可以更好地作为“ foo = ANY(ARRAY [a,b,c]))”进行处理-尤其重要的是,您可以转换为传入可变大小的数组必须为每一个构造一个特殊的语句。
  • 要对函数的结果进行排序,请考虑使用子选择。“ SELECT foo FROM(选择fun(z)作为blaz的foo)tmp顺序为1”。
  • 用coalesce替换nvl
  • 用LIMIT 1替换rownum <= 1
  • 用string_agg替换listagg
  • 用递归替换递归层次结构(以/开头/先于/先于)
  • 用except代替减号
  • 用CURRENT_TIMESTAMP替换SYSDATE
  • 将trunc(sysdate)替换为CURRENT_DATE
  • 用DATE(datelastupdted)或datelastupdated :: date替换trunc(datelastupdated)
  • 用'-infinity':: date替换诸如to_date('01 Jan 1900')之类的人工日期标记/围栏
  • 删除双表引用
  • 用case语句替换解码
  • 用独特替换独特
  • 用:: integer替换to_number
  • 用〜或〜*替换regexp_like()
  • 用%运算符替换mod
  • 用INSERT ... ON CONFLICT… DO UPDATE/NOTHING替换merge
  • 使用sys_guid()作为gen_random_uuid()的默认值来更改任何表的默认值
  • oracle的pivot 和unpivot在postgres中不起作用-使用unnest
  • ORDER BY NLSSORT(english, 'NLS_SORT=generic_m') 变为ORDER BY gin(insensitive_query(english) gin_trgm_ops)
  • 用U&'替换UNISTR(
  • Oracle:使用IS NULL检查空字符串;postgres使用空字符串和null是不同的
  • 如果varchar / text列具有唯一索引,则需要检查以确保在添加或更新列之前将空字符串更改为null。
  • PostgreSQL需要一个用括号括起来的子SELECT,并且必须为其提供一个别名。-- SELECT * FROM ( ) A
  • order by子句中的所有函数都必须移至select语句(例如,order by lower(column_name))
  • 任何数字/整数/ bigint /等排序。IN语句中的内容不能为字符串(包括'null'-不必费心尝试使用null =“”,它就行不通)。
  • 将NULL与NOT NULL串联将导致NULL。
  • 注意任何左联接。如果在where或select子句中使用左连接中的列,则该列可能为null。
  • 对于序列,请使用nextval('sequence_name')而不是sequence_name.nextval

 
从Oracle迁移到Postgres时,还有其他一些非常方便的工具:
Orafce-捆绑在Oracle函数中的扩展-https: //github.com/orafce/orafce
OracleFDW-外部数据包装器,可直接从Postgres查询到Oracle- https://github.com/laurenz/oracle_fdw