我需要将PostgreSQL数据库的结构转换为Oracle。在PostgreSQL中,我有一个包含数据的postgres
数据库。
在Oracle中,我有一个空白数据库,我想在其中编写PostgreSQL中的postgres
数据库。
事实上,我不需要数据,只需要结构(关系)。
为此,我使用Liquibase。我使用以下命令从PostgreSQL获取变更日志:
liquibase
--driver=org.postgresql.Driver
--classpath="C:db_driverspostgresql-9.3-1102.jdbc3.jar"
--changeLogFile="./postgresql_changelog.xml"
--url="jdbc:postgresql://localhost:5432/postgres"
--username=schema_name_here
--password=**************
--logLevel=debug
--defaultSchemaName=sep
generateChangeLog
之后,我尝试在Oracle数据库中创建对象:
liquibase
--driver=oracle.jdbc.OracleDriver
--classpath="C:db_driversojdbc14.jar"
--changeLogFile="./postgresql_changelog.xml"
--url="jdbc:oracle:thin:@ip_here:orabeta"
--username=***
--password=***
update
不起作用:ORA-00902
以下是postgresql_changelog.xml的一个片段:
...
<changeSet author="Alexey (generated)" id="1409146335011-53">
<createTable tableName="TABLE1A">
<column name="total_pk" type="INT8">
<constraints nullable="false"/>
</column>
<column name="form_fk" type="INT8">
<constraints nullable="false"/>
</column>
...
我还生成了一个纯SQL文件:
liquibase
--driver=oracle.jdbc.OracleDriver
--classpath="C:db_driversojdbc14.jar"
--changeLogFile="./postgresql_changelog.xml"
--url="jdbc:oracle:thin:@ip_here:orabeta"
--username=***
--password=***
updateSQL > update.sql
这里是update.sql:的一个片段
...
CREATE TABLE SCHEMA_HERE.TABLE1A (total_pk INT8 NOT NULL, form_fk INT8, .....etc );
INSERT INTO SCHEMA_HERE.TABLE1A (ID, FORM_ID, ...etc)
...
我想生成一个文件,其中所有的数据类型都对应于目标数据库,即我想要创建的数据库。我可以编写一个简单的解析器来替换数据类型,但这不是正确的解决方案——可能是许多数据库。
是否可以使用目标数据库的数据类型生成XML/SQL输出?
或者可能有一个选项允许生成具有"抽象"数据类型的输出?例如,使用不在真实数据库中的数据类型,而不是INT8
-抽象整数数据类型等。
实际上,需要手动更正生成文件中的数据类型(不仅是数据类型,还有数据库的所有细节(减少约束名称、索引等的长度)。数据类型不会自动转换
例如:
...
<changeSet author="Alexey (generated)" id="1409146335011-53">
<createTable tableName="TABLE1A">
<!-- replace INT8 to NUMBER(16) for Oracle (for example) -->
<column name="total_pk" type="INT8">
<constraints nullable="false"/>
</column>
<!-- replace INT4 to NUMBER(10) for Oracle (for example) -->
<column name="form_fk" type="INT4">
<constraints nullable="false"/>
</column>
...
之后执行命令:
liquibase
--driver=oracle.jdbc.OracleDriver
--classpath="C:db_driversojdbc14.jar"
--changeLogFile="./postgresql_changelog.xml"
--url="jdbc:oracle:thin:@ip_here:orabeta"
--username=***
--password=***
update
该结构将在目标数据库上生成。
但是,实际上,可以使用"抽象"数据类型,如文档中所写:Liquibase,Column标签
为了帮助使脚本数据库独立,以下"泛型"数据类型将转换为正确的数据库实现:
BOOLEAN
CURRENCY
UUID
CLOB
BLOB
DATE
DATETIME
TIME
BIGINT
此外,指定
java.sql.Types.*
类型将转换为正确的类型。如果需要,可以包括精度。这是一些例子:java.sql.Types.TIMESTAMP
java.sql.Types.VARCHAR(255)
并且可以在没有DDL的情况下复制结构(在没有DML的情况下也可以复制数据)。
是否同样可以迁移数据(选项--diffTypes = "data"
):
liquibase
--driver=org.postgresql.Driver
--classpath="C:db_driverspostgresql-9.3-1102.jdbc3.jar"
--changeLogFile="./data.xml"
--url="jdbc:postgresql://localhost:5432/postgres"
--username=***
--password=***
--logLevel=debug
--defaultSchemaName=schema_name_here
--diffTypes="data"
generateChangeLog
临时禁用所有约束(手动)后:
liquibase
--driver=oracle.jdbc.OracleDriver
--classpath="C:db_driversojdbc14.jar"
--changeLogFile="./data.xml"
--url="jdbc:oracle:thin:@ip_here:orabeta"
--username=***
--password=***
--logLevel=debug
update