diff --git a/mysql2pgsql/lib/mysql_reader.py b/mysql2pgsql/lib/mysql_reader.py index 94dfc96..cc59403 100644 --- a/mysql2pgsql/lib/mysql_reader.py +++ b/mysql2pgsql/lib/mysql_reader.py @@ -10,6 +10,16 @@ re_column_length = re.compile(r'\((\d+)\)') re_column_precision = re.compile(r'\((\d+),(\d+)\)') re_key_1 = re.compile(r'CONSTRAINT `(\w+)` FOREIGN KEY \(`(\w+)`\) REFERENCES `(\w+)` \(`(\w+)`\)') +# NB: according to the MySQL docs (5.5): +# SET DEFAULT: This action is recognized by the parser, but InnoDB rejects +# table definitions containing ON DELETE SET DEFAULT or ON UPDATE +# SET DEFAULT clauses. +# Thus not searching for it. RESTRICT is the default behaviour and +# SHOW CREATE TABLE will _not_ output it (even when explicitly defined before). +# RESTRICT is assumed as default for Postgres if nothing is defined +# according to SHOW CREATE TABLE info. +re_key_1_on_delete = re.compile(r'ON DELETE (NO ACTION|CASCADE|SET NULL)') +re_key_1_on_update = re.compile(r'ON UPDATE (NO ACTION|CASCADE|SET NULL)') re_key_2 = re.compile(r'KEY `(\w+)` \((.*)\)') re_key_3 = re.compile(r'PRIMARY KEY \((.*)\)') @@ -160,6 +170,13 @@ def _load_indexes(self): index['column'] = match_data.group(2) index['ref_table'] = match_data.group(3) index['ref_column'] = match_data.group(4) + # NB: MySQL handles not defining a referential action, + # NO ACTION and RESTRICT all like RESTRICT. That's why i + # chose RESTRICT as default for the translation to Postgres. + ondel_match = re_key_1_on_delete.search(line) + index['on_delete'] = ondel_match.group(1) if ondel_match else 'RESTRICT' + onupd_match = re_key_1_on_update.search(line) + index['on_update'] = onupd_match.group(1) if onupd_match else 'RESTRICT' self._foreign_keys.append(index) continue match_data = re_key_2.search(line) diff --git a/mysql2pgsql/lib/postgres_writer.py b/mysql2pgsql/lib/postgres_writer.py index f66b08a..6fafb49 100644 --- a/mysql2pgsql/lib/postgres_writer.py +++ b/mysql2pgsql/lib/postgres_writer.py @@ -251,11 +251,13 @@ def write_constraints(self, table): constraint_sql = [] for key in table.foreign_keys: constraint_sql.append("""ALTER TABLE "%(table_name)s" ADD FOREIGN KEY ("%(column_name)s") - REFERENCES "%(ref_table_name)s"(%(ref_column_name)s);""" % { + REFERENCES "%(ref_table_name)s"(%(ref_column_name)s) %(on_delete)s %(on_update)s;""" % { 'table_name': table.name, 'column_name': key['column'], 'ref_table_name': key['ref_table'], - 'ref_column_name': key['ref_column']}) + 'ref_column_name': key['ref_column'], + 'on_delete': key['on_delete'] if key['on_delete'] == '' else 'ON DELETE %s' % (key['on_delete']), + 'on_update': key['on_update'] if key['on_update'] == '' else 'ON UPDATE %s' % (key['on_update'])}) return constraint_sql def close(self):