Skip to content
This repository has been archived by the owner on May 10, 2023. It is now read-only.

Commit

Permalink
Merge pull request #46 from gms8994/master
Browse files Browse the repository at this point in the history
Copy triggers existing on MySQL tables to Postgres
  • Loading branch information
kworr committed Dec 23, 2013
2 parents 6583de4 + b87af1b commit 51ee5dc
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 2 deletions.
5 changes: 5 additions & 0 deletions mysql2pgsql/lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def status_logger(f):
constraints_template = 'ADDING CONSTRAINTS ON %s'
write_contents_template = 'WRITING DATA TO %s'
index_template = 'ADDING INDEXES TO %s'
trigger_template = 'ADDING TRIGGERS TO %s'
statuses = {
'truncate': {
'start': start_template % truncate_template,
Expand All @@ -72,6 +73,10 @@ def status_logger(f):
'start': start_template % index_template,
'finish': finish_template % index_template,
},
'write_triggers': {
'start': start_template % trigger_template,
'finish': finish_template % trigger_template,
},
}

@wraps(f)
Expand Down
7 changes: 5 additions & 2 deletions mysql2pgsql/lib/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,19 @@ def convert(self):

if not self.supress_ddl:
if self.verbose:
print_start_table('START CREATING INDEXES AND CONSTRAINTS')
print_start_table('START CREATING INDEXES, CONSTRAINTS, AND TRIGGERS')

for table in tables:
self.writer.write_indexes(table)

for table in tables:
self.writer.write_constraints(table)

for table in tables:
self.writer.write_triggers(table)

if self.verbose:
print_start_table('DONE CREATING INDEXES AND CONSTRAINTS')
print_start_table('DONE CREATING INDEXES, CONSTRAINTS, AND TRIGGERS')

if self.verbose:
print_start_table('\n\n>>>>>>>>>> FINISHED <<<<<<<<<<')
Expand Down
22 changes: 22 additions & 0 deletions mysql2pgsql/lib/mysql_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,10 @@ def __init__(self, reader, name):
self._name = name
self._indexes = []
self._foreign_keys = []
self._triggers = []
self._columns = self._load_columns()
self._load_indexes()
self._load_triggers()

def _convert_type(self, data_type):
"""Normalize MySQL `data_type`"""
Expand Down Expand Up @@ -181,6 +183,22 @@ def _load_indexes(self):
self._indexes.append(index)
continue

def _load_triggers(self):
explain = self.reader.db.query('SHOW TRIGGERS WHERE `table` = \'%s\'' % self.name)
for row in explain:
if type(row) is tuple:
trigger = {}
trigger['name'] = row[0]
trigger['event'] = row[1]
trigger['statement'] = row[3]
trigger['timing'] = row[4]

trigger['statement'] = re.sub('^BEGIN', '', trigger['statement'])
trigger['statement'] = re.sub('^END', '', trigger['statement'], flags=re.MULTILINE)
trigger['statement'] = re.sub('`', '', trigger['statement'])

self._triggers.append(trigger)

@property
def name(self):
return self._name
Expand All @@ -197,6 +215,10 @@ def indexes(self):
def foreign_keys(self):
return self._foreign_keys

@property
def triggers(self):
return self._triggers

@property
def query_for(self):
return 'SELECT %(column_names)s FROM `%(table_name)s`' % {
Expand Down
13 changes: 13 additions & 0 deletions mysql2pgsql/lib/postgres_db_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,19 @@ def write_indexes(self, table):
for sql in index_sql:
self.execute(sql)

@status_logger
def write_triggers(self, table):
"""Send DDL to create the specified `table` triggers
:Parameters:
- `table`: an instance of a :py:class:`mysql2pgsql.lib.mysql_reader.MysqlReader.Table` object that represents the table to read/write.
Returns None
"""
index_sql = super(PostgresDbWriter, self).write_triggers(table)
for sql in index_sql:
self.execute(sql)

@status_logger
def write_constraints(self, table):
"""Send DDL to create the specified `table` constraints
Expand Down
11 changes: 11 additions & 0 deletions mysql2pgsql/lib/postgres_file_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,17 @@ def write_constraints(self, table):
"""
self.f.write('\n'.join(super(PostgresFileWriter, self).write_constraints(table)))

@status_logger
def write_triggers(self, table):
"""Write TRIGGERs existing on `table` to the output file
:Parameters:
- `table`: an instance of a :py:class:`mysql2pgsql.lib.mysql_reader.MysqlReader.Table` object that represents the table to read/write.
Returns None
"""
self.f.write('\n'.join(super(PostgresFileWriter, self).write_triggers(table)))

@status_logger
def write_contents(self, table, reader):
"""Write the data contents of `table` to the output file.
Expand Down
26 changes: 26 additions & 0 deletions mysql2pgsql/lib/postgres_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,32 @@ def write_constraints(self, table):
'ref_column_name': key['ref_column']})
return constraint_sql

def write_triggers(self, table):
trigger_sql = []
for key in table.triggers:
trigger_sql.append("""CREATE OR REPLACE FUNCTION %(fn_trigger_name)s RETURNS TRIGGER AS $%(trigger_name)s$
BEGIN
%(trigger_statement)s
RETURN NULL;
END;
$%(trigger_name)s$ LANGUAGE plpgsql;""" % {
'table_name': table.name,
'trigger_time': key['timing'],
'trigger_event': key['event'],
'trigger_name': key['name'],
'fn_trigger_name': 'fn_' + key['name'] + '()',
'trigger_statement': key['statement']})

trigger_sql.append("""CREATE TRIGGER %(trigger_name)s %(trigger_time)s %(trigger_event)s ON %(table_name)s
FOR EACH ROW
EXECUTE PROCEDURE fn_%(trigger_name)s();""" % {
'table_name': table.name,
'trigger_time': key['timing'],
'trigger_event': key['event'],
'trigger_name': key['name']})

return trigger_sql

def close(self):
raise NotImplementedError

Expand Down

0 comments on commit 51ee5dc

Please sign in to comment.