38

I've looked around and can't seem to find anything that answers this specific question.

What is the simplest way to move data from an MS SQL Server 2005 DB to a Postgres install (8.x)?

I've looked into several utilities like "Full Convert Enterprise", etc, and they all fail for one reason or another, ranging from strange errors that make it blow up to inserting nulls rather than actual data (wth?).

I'm looking at a DB with all table except for a single view, no stored procs, functions, etc.

At this point I'm about to write a small utility to do it for me, I just can't believe that's necessary. Surely there's something somewhere that can do this? I'm not even too worried about cost, although free is preferable :)

2

6 Answers 6

51

I don't know why nobody has mentioned the simplest and easiest way using robust MS SQL Server Management Studio.

Simply you just need to use the built-in SSIS Import/export feature. You can follow these steps:

  1. Firstly, you need to install the PostgreSQL ODBC Driver for Windows. It's very important to install the correct version in terms of CPU arch (x86/x64).

  2. Inside Management Studio, Right click on your database: Tasks -> Export Data

  3. Choose SQL Server Native Client as the data source.

  4. Choose .Net Framework Data Provider for ODBC as the destination driver.

  5. Set the Connection String to your database in the following form:

    Driver={PostgreSQL ODBC Driver(UNICODE)};Server=;Port=;Database=;UID=;PWD=

  6. In the next page, you just need to select which tables you want to export. SQL Server will generate a default mapping and you are free to edit it. Probably you`ll encounter some Type Mismatch problems which take some time to solve. For example, if you have a boolean column in SQL Server you should export it as int4.

Microsoft Docs hosts a detailed description of connecting to PostgreSQL through ODBC.

PS: if you want to see your installed ODBC Driver, you need to check it via ODBC Data Source Administrator.

Sign up to request clarification or add additional context in comments.

11 Comments

Yes, as per step 1 the chosen driver architecture (32 vs 64 bit) is important. And somehow I needed the 32-bit ODBC driver to export data from 64-bit SQL Server Management Studio. I think it's running an external exporter tool that is still 32-bit.
thanks, this works better than any other tools/ways i have tried. i had to change the name of the Driver.
This helped a lot. A couple of gotchas for me, that might be helpful for future viewers: 1) You'll need to add a data source name for the Postgres driver 2) Make sure your data source name matches the value set for Drive={your-data-source-name}
Modern driver has its name changed to PostgreSQL Unicode.
Here's a screenshot of my working configs for anyone interested. Installing both the 32-bit and 64-bit versions of the ODBC driver seemed to help me.
|
9

Take a look at the Software Catalogue. Under Administration/development tools I see DBConvert for MS SQL & PostgreSQL. Probably there are other similar tools listed.

3 Comments

perfect, that's exactly what I was looking for. I took it for a test drive, liked it so I purchased the full version and it's working like a champ. For those not looking for this specific solution, but solutions that are similar, they offer tools for converting and synchronizing between MSSQL, Postgres,Oracle,MS Access, Firebird, etc. I can only speak for the MSSQL/Postgres conversions, but if those conversions are any indication, this software package is well worth the $79.
@Milen A. Radev, +1 Great!
Warning! It adds %number%-TRIAL-%number% at the beginning for text fields when using the trial version.
5

You can use the MS DTS functionality (renamed to SSIS in the latest version I think). One issue with the DTS is that I've been unable to make it do a commit after each row when loading the data into pg. Which is fine if you only have a couple of 100k rows or so, but it's really very slow.

I usually end up writing a small script that dumps the data out of SQLServer in CSV format, and then use COPY WITH CSV on the PostgreSQL side.

Both those only take care of the data though. Taking care of the schema is a bit harder, since datatypes don't necessarily map straight over. But it can easily be scripted together with a static load of the schema. If the schema is simple (just varchar/int datatypes for example), that part can also easily be scripted off the data in INFORMATION_SCHEMA.

Comments

1

I had a problem with SSMS and bit values (1/0 in SqlServer, but in PostgreSql it is true/false) so I searched and stopped on DBeaver, it's free and pretty much maps the tables and columns all by himself so it's very easy. On a relatively small values (~100 tables, ~20mil rows) it performs fine, under 30min.
However, on large tables (~10mil+ rows) with significant amount of columns it may struggle. I ended up using DBeaver for everything except the big table which I exported via SSIS in CSV format and imported in PostgreSql via COPY command. Also dropping PK, Contraints, indexes on the large table and re-adding them after the migration helped a lot.
If you're running PostgreSql on linux, you may consider using FDW which can import schema and data without much effort.

1 Comment

I also ran into the BIT vs BOOLEAN problem, but discovered what to do. Go into the ODBC Data Source Administrator, select your data source and click the Configure... button. In the Options section click the Datasource button. In the Data Type Options section, uncheck the Bools as Char checkbox. Now it will accurately convert BIT to BOOLEAN. Unfortunately I am also running into horrible performance for very large tables, which will likely require me to find an alternate means to migrate those tables.
0

Well there are .NET bindings for MS SQL Server 2005 (obviously) and also for PostgreSQL. So it would only take a few lines of code to code up a program that could transfer data safely from one to the other. The view would probably have to be done manually as Postgres doesn't use the same language for views as SQL Server.

2 Comments

yes, but that is going to require a lot of maintenance to keep up with over time, I'd prefer something that didn't require me to dive into code every time the DB schema changes. and if I'm making it generic then it becomes not so simple as now I'm having to make decisions based upon datatypes, etc.
Well, I don't think there is going to be an easy route. See here wiki.postgresql.org/wiki/… for some of the issues involved. It's much more likely that you will be able to code something that works in your situation than that someone will be able to create a tool that works for all.
0

This answer is to help summarize current connection string because someone may overlooked the comment.

Current version of ODBC connection string is:

For 32-bit system

Driver={PostgreSQL UNICODE};Server=192.168.1.xxx;Port=5432;Database=yourDBname;Uid=postgres;Pwd=admin;

For 64-bit system

Driver={PostgreSQL UNICODE(x64)};Server=192.168.1.xxx;Port=5432;Database=yourDBname;Uid=postgres;Pwd=admin;

You can check the driver name by typing ODBC in windows search. And open ODBC Data Source Administrator

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.