If you’ve decided to move a few tables from MySQL to PostgreSQL, these few tips might help. I won’t get into any reasons why to move to PostgreSQL or not. There are already many discussions on the topic.

Create Syntax

The first five listed need to be done in order; the rest can be in any.

  • Replace mediumint with int
  • Replace tinyint with smallint
  • Replace int\([0-9]+\) with int. (This is a regular expression that will find any instance of int() where there is at least one number between the parenthesis)
  • Remove all instances of NOT NULL I don’t know what I was thinking here.
  • Replace int\s+auto_increment with SERIAL (Another regular expression that will catch a case with multiple spaces between int and auto_increment).
    1. UPDATE: try int(\s+|\s+NOT NULL\s+)auto_increment instead to catch when not null is in between int and auto.
    2. UPDATE: try (smallint|int)(\s+|\s+NOT NULL\s+)auto_increment so it will catch the case when it is smallint as well.
  • Remove ENGINE=MyISAM (Change if you use a different engine, i.e. innodb)
  • Remove DEFAULT CHARSET=latin1 (Change if you use a different character set)
  • Remove AUTO_INCREMENT=[0-9]+ (Another regular expression to find all cases of an auto increment number)
  • Remove IF NOT EXISTS
  • Remove all `


phpMyAdmin has options when exporting that may make some of these steps unnecessary. If you keep the create sql in a separate file from the insert sql, you save yourself from changing any data that may look like some of the above when it isn’t actual sql syntax.

Auto Increment and Serial

After running the create table SQL, a sequence table will be created for the serial column. This sequence will need to be altered if the auto increment won’t be starting at one. A query like the one below will need to be done for each table.

ALTER SEQUENCE tab_name_col_name_seq RESTART WITH #;


To define a column to be indexed, it is done in a separate query. Remove anything that looks like KEY username (username). The query to run after the create table query should look like

CREATE INDEX index_name ON table_name (column_name);

Insert Syntax

The syntax here is pretty close, just one thing needs to be changed.

  • Replace “” with \”. (MySQL and PostgreSQL use different methods of escaping these quotes.)

Make sure the complete inserts option is enabled and extended inserts isn’t. PosgreSQL doesn’t support multiple inserts with one query the same way. (As far as I know at the moment)

Your Mileage May Vary

This was tested using phpMyAdmin export and phpPgAdmin SQL executing. The regular expressions and other replace commands were done in jEdit. With my few test cases I probably didn’t catch everything. Let me know how it works out for you.

I use webfaction to host a lot of my django projects. It has an easy setup that will get you developing quickly and a great community of talented programmers. There is also a quick setup for rails, wordpress, and a lot more.

Related posts:

  1. Careful with Numeric Data Types in MySQL  TINYINT can be set to length of 4, but that doesn’t mean the max value is 9999. A tiny int...
  2. How To Use Triggers to Track Changes in MySQL  Setting constraints and rules in the database is better than writing special code to handle the same task since it...
  3. How to Break a MySQL Left Join  Care must be taken when placing conditions on the results of the right-hand table of a LEFT JOIN because it...