如何将PostgreSQL数据库迁移到SQLServer数据库?

时间:2011-07-03 15:45:59

标签: sql-server database postgresql migration

我有一个PostgreSQL数据库,我想转移到SQL Server - 架构和数据。我很穷,所以我不想付钱。我也很懒,所以我不想做很多工作。目前我正在按表格进行此表,并且有大约100个表要做。这非常乏味。

是否有某种技巧可以满足我的需求?

2 个答案:

答案 0 :(得分:50)

您应该可以在此Serverfault页面中的已接受答案中找到一些有用的信息:https://serverfault.com/questions/65407/best-tool-to-migrate-a-postgresql-database-to-ms-sql-2005

如果您可以在没有数据的情况下转换架构,则可以使用此命令缩短数据的步骤:

pg_dump --data-only --column-inserts your_db_name > data_load_script.sql

此加载速度非常慢,但--column-inserts选项会为每行数据生成最通用的INSERT语句,并且应该是兼容的。

编辑:有关转换架构的建议如下:

我首先要转储模式,但删除任何与所有权或权限有关的内容。这应该足够了:

pg_dump --schema-only --no-owner --no-privileges your_db_name > schema_create_script.sql

修改此文件,将行BEGIN TRANSACTION;添加到开头,将ROLLBACK TRANSACTION;添加到结尾。现在,您可以加载它并在SQL Server的查询窗口中运行它。如果出现任何错误,请确保转到文件的底部,突出显示ROLLBACK语句并运行它(通过在突出显示语句时按F5)。

基本上,您必须解决每个错误,直到脚本干净地运行。然后,您可以将ROLLBACK TRANSACTION更改为COMMIT TRANSACTION并最后一次运行。

不幸的是,我无法帮助您看到哪些错误,因为我从未从PostgreSQL转到SQL Server,只是反过来。然而,有些事情我认为是一个问题(显然,不是一个详尽的清单):

  • PostgreSQL通过使用NOT NULL INTEGERSEQUENCE字段链接到DEFAULT来自动增加字段。在SQL Server中,这是一个IDENTITY列,但它们并不完全相同。我不确定它们是否相同,但如果你的原始模式充满了“id”字段,那么你可能会遇到麻烦。我不知道SQL Server是否有CREATE SEQUENCE,因此您可能需要删除它们。
  • 数据库函数/存储过程不在RDBMS平台之间转换。您需要删除所有CREATE FUNCTION语句并手动翻译算法。
  • 注意数据文件的编码。我是Linux用户,所以我不知道如何在Windows中验证编码,但是你需要确保SQL Server所期望的与从PostgreSQL导入的文件相同。 pg_dump有一个选项--encoding=,可让您设置特定的编码。我似乎记得Windows倾向于对Unicode使用两字节UTF-16编码,其中PostgreSQL使用UTF-8。由于UTF-16输出,我从SQL Server到PostgreSQL有一些问题所以值得研究。
  • PostgreSQL数据类型TEXT只是VARCHAR,没有最大长度。在SQL Server中,TEXT是复杂的(并且已弃用)。声明为TEXT的原始模式中的每个字段都需要针对相应的SQL Server数据类型进行检查。
  • SQL Server为UNICODE数据提供了额外的数据类型。我不太熟悉它提出建议。我只是指出这可能是一个问题。

答案 1 :(得分:1)

我找到了一种更快捷,更简单的方法来实现这一目标。

首先将表(或查询)复制到制表符分隔文件,如下所示:

COPY (SELECT siteid, searchdist, listtype, list, sitename, county, street, 
   city, state, zip, georesult, elevation, lat, lng, wkt, unlocated_bool, 
   id, status, standard_status, date_opened_or_reported, date_closed, 
   notes, list_type_description FROM mlocal) TO 'c:\SQLAzureImportFiles\data_script_mlocal.tsv' NULL E''

接下来,您需要在SQL中创建表,这不会为您处理任何架构。架构必须按字段顺序和数据类型匹配导出的tsv文件。

最后,运行SQL的bcp实用程序来引入tsv文件,如下所示:

bcp MyDb.dbo.mlocal in "\\NEWDBSERVER\SQLAzureImportFiles\data_script_mlocal.tsv" -S tcp:YourDBServer.database.windows.net -U YourUserName -P YourPassword -c

我遇到的一些值得注意的事情。 Postgres和SQL Server以不同方式处理布尔字段。您的SQL Server架构需要将布尔字段设置为varchar(1),结果数据将是' f',' t'或者为null。然后,您必须将此字段转换为一点。做类似的事情:

ALTER TABLE mlocal ADD unlocated bit;
UPDATE mlocal SET unlocated=1 WHERE unlocated_bool='t';
UPDATE mlocal SET unlocated=0 WHERE unlocated_bool='f';
ALTER TABLE mlocal DROP COLUMN unlocated_bool;

另一件事是两个平台之间的地理/几何领域非常不同。使用ST_AsText(geo)将几何字段导出为WKT,并在SQL Server端进行适当转换。

可能有更多的不兼容性需要这样的调整。

EDIT。因此,虽然这种技术在技术上有效,但我试图将100多个记录从100多个表转移到SQL Azure,而bcp到SQL Azure的结果非常糟糕。我一直在间歇性地无法打开BCP主机数据文件错误,服务器间歇性地超时,并且由于某种原因某些记录没有被传输而没有任何错误或问题的迹象。因此,这种技术对于将大量数据传输到Azure SQL并不稳定。