Log on:
Powered by Elgg

Caius :: Blog :: On Migrating SQL

September 15, 2007

I was originally planning to write about using the C APIs of PostgreSQL, MySQL and SQLite, but as I don't have time for that today,I'm going to talk about something I've been doing the past couple of days: Migrating from SQLite to PostgreSQL for both my forum and my MUD.

First you might be wondering why I'm using the less supported PostgreSQL instead of MySQL. Frankly I will not enter that hornet's nest of a discussion here. Flame wars rage on the internet on that subject, and it's just as silly as "my programming language is better than yours". You use the tools that fits your purposes. Simple as that. In the following I'll talk about migrating both the forum and the mud in a single discussion, because they're both SQLite -> PostgreSQL anyway.

The first thing I did was to dump the entire databases into a text file of SQL statements. All SQL engines I've seen have tools for doing this. Technically you can simply read that same file into another database. However, it's rarely that simple. PostgreSQL has different syntax that SQLite for such things as making an autoincrement field:

SQLite:
CREATE TABLE test_table (
        a INTEGER PRIMARY KEY,
        b INTEGER
);

PostgreSQL:
CREATE TABLE test_table (
        a SERIAL,
        b INT
);

So obviously I had to change a few schemas. Using these autoincrement fields is also different:

SQLite:
INSERT INTO test_table VALUES ( NULL, 123 );

PostgreSQL:
INSERT INTO test_table VALUES ( DEFAULT, 123 );

So this forced me to change a few SQL statements scattered around the code as well. But it doesn't stop there. Case insensitive matching in queries also differ:

SQLite:
DELETE FROM players WHERE name LIKE 'caius';

PostgreSQL:
DELETE FROM players WHERE name ~* 'caius';

This is because the LIKE operator has slightly different meaning in the two engines. Again I had to change quite a few SQL statements in my code. At this point importing the data into the PostgreSQL database, and reading from it worked properly. However, I soon encountered another problem. Postgres refused to insert new rows into tables with autoincrement fields! Arg! The reason is that the engine keeps a separate sequence table to keep track of the index. So I had to update this counter manually. If we assume the top id in the above table is 14, we must send the following query to the database:

PostgreSQL:
ALTER SEQUENCE test_table_id_seq RESTART WITH 15;

So it's in the form "table name" + "field name" + "seq". Now, FINALLY, everything ran smoothly.

Now, you may wonder why the database engines doesn't do these things similarly? The reason is that they implement extra features that aren't a part of the SQL standard, and they each do it their own way. This is why migrating SQL data can be a pain, especially if you use non-standard features.

That's it for today. Cheers. 

Keywords: database, PostgreSQL, SQL, SQLite

Posted by Caius


Comments

  1. That is the reason i've never migrated away from mySQL.  I've been wanting to switch to PosgreSQL for years and this new incarnation of MudDomain may force me to do so as it grows and the need for some of the advanced features of PosgreSQL become needed.  I tried once to convert a site over and frankily gave up because of laziness after a few hours.  Thanks for your post they really are good.

    default user icon" width="50" height="50" align="left" alt="" />Paradigm on Saturday, 15 September 2007, 08:51 MDT # |

  2. I imagine converting an exiting site with lots and lots of data would turn into a nightmare from hell. Even if the software running the site supports both types of databases.

    We've been adding PostgreSQL support to QSF to go into version 2.0.0 and while I'm not the one doing the work I can already see the major differences in the table structures. So it certainly looks to me like once you've chosen an engine it's highly desirable to stick with it.

    SamsonSamson on Saturday, 15 September 2007, 11:08 MDT # |

  3. I agree that migrating to a different database engine rarely is worth the effort. The only reason I did it was because SQLite isn't really intended for sharing data between applications. And since I need to do that I ended up converting to PostgreSQL.

    CaiusCaius on Sunday, 16 September 2007, 10:03 MDT # |

  4. Speaking of QSF, with PostgreSQL support I'll probably check it out myself. I'm looking for something more than my current forum anyway.

    CaiusCaius on Wednesday, 19 September 2007, 12:35 MDT # |

  5. Working more with PostgreSQL (pgsql) I've found more issues that are worth considering. I'm finding that a lot of the software that "supports" pgsql haven't been tested properly. The database interface itself usually works, but as pgsql has a much stricter SQL syntax than MySQL there are some things that can cause problems. For example, MySQL has an extension that allows you to replace 'AND' with '&&' in queries. This is not a part of the standard, and pgsql does not support it.

    CaiusCaius on Sunday, 23 September 2007, 07:02 MDT # |

You must be logged in to post a comment.