Tips for MySQL to PostgreSQL Switch
Posted on July 2nd, 2008 by Greg Allard in MySQL |
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).
- UPDATE: try int(\s+|\s+NOT NULL\s+)auto_increment instead to catch when not null is in between int and auto.
- 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
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 #;
Indexes
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.
For More MySQL Tips
Check out these other posts:
Add New Comment
Viewing 6 Comments
Thanks. Your comment is awaiting approval by a moderator.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
WTF!? This can seriously break many schemas. Don't do this.
Postres supports multiple-row inserts only in latest versions (8.3+ IIRC).
another useful replacement may be CURRENT_TIMESTAMP with NOW() and timestamp with timestamp without time zone, etc.
Do you already have an account? Log in and claim this comment.
Thanks for the comment. I updated the post to cross out the NOT NULL part, I think I meant that only for the auto_increment part, but messed it up.
I'll check out the newer versions to see what's been changed. I was on 7.4.7.
Do you already have an account? Log in and claim this comment.
- An enum column in MySQL is equal to a varchar with a check constraint in PostgreSQL, for example:
column_name enum('foo', 'bar') is equal to column_name varchar(3) check (column_name IN ('foo', 'bar'))
- The blob datatype in MySQL is equal to a bytea datatype in PostgreSQL
Also, when truncating a table, I do not believe PostgreSQL resets the sequence for serial columns, so it will need to be done manually.
Obviously there are more differences when moving to PostgreSQL, but these are most of the big ones for CREATE TABLE statements.
Just a little FYI. I wrote these all out, but forgot my email. Your blog is very unfriendly to comments without an email, as in I lost my comments.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
CREATE TABLE manila_area_tbl
(
area_no tinyint(4) NOT NULL auto_increment,
area_name varchar(65) NOT NULL,
disp_flag char(1) NOT NULL default '1',
disp_no tinyint(4) NOT NULL,
del_flag char(1) NOT NULL default '0',
PRIMARY KEY (`area_no`),
KEY disp_no` (`disp_no`),KEY `del_flag` (`del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=25;
Do you already have an account? Log in and claim this comment.
Try running these 4 queries.
CREATE TABLE manila_area_tbl
(
area_no SERIAL,
area_name varchar(65) NOT NULL,
disp_flag char(1) NOT NULL default 1,
disp_no smallint NOT NULL,
del_flag char(1) NOT NULL default 0,
PRIMARY KEY (area_no)
) ;
CREATE INDEX disp_no ON manila_area_tbl (disp_no);
CREATE INDEX del_flag ON manila_area_tbl (del_flag);
ALTER SEQUENCE manila_area_tbl_area_no_seq RESTART WITH 25;
Add New Comment
Trackbacks