''' Create the web2py code needed to access your mysql legacy db. To make this work all the legacy tables you want to access need to have an "id" field. This plugin needs: mysql mysqldump installed and globally available. Under Windows you will probably need to add the mysql executable directory to the PATH variable, you will also need to modify mysql to mysql.exe and mysqldump to mysqldump.exe below. Just guessing here :) Access your tables with: legacy_db(legacy_db.mytable.id>0).select() If the script crashes this is might be due to that fact that the data_type_map dictionary below is incomplete. Please complete it, improve it and continue. Created by Falko Krause, minor modifications by Massimo Di Pierro, Ron McOuat and Marvi Benedet ''' import subprocess import re import sys data_type_map = dict( varchar='string', int='integer', integer='integer', tinyint='integer', smallint='integer', mediumint='integer', bigint='integer', float='double', double='double', char='string', decimal='integer', date='date', #year = 'date', time='time', timestamp='datetime', datetime='datetime', binary='blob', blob='blob', tinyblob='blob', mediumblob='blob', longblob='blob', text='text', tinytext='text', mediumtext='text', longtext='text', ) def mysql(database_name, username, password, host): p = subprocess.Popen(['mysql', '--user=%s' % username, '--password=%s' % password, '--host=%s' % host, '--execute=show tables;', database_name], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) sql_showtables, stderr = p.communicate() tables = [re.sub( '\|\s+([^\|*])\s+.*', '\1', x) for x in sql_showtables.split()[1:]] connection_string = "legacy_db = DAL('mysql://%s:%s@%s/%s')" % ( username, password, host, database_name) legacy_db_table_web2py_code = [] for table_name in tables: #get the sql create statement p = subprocess.Popen(['mysqldump', '--user=%s' % username, '--password=%s' % password, '--host=%s' % host, '--skip-add-drop-table', '--no-data', database_name, table_name], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) sql_create_stmnt, stderr = p.communicate() if 'CREATE' in sql_create_stmnt: # check if the table exists #remove garbage lines from sql statement sql_lines = sql_create_stmnt.split('\n') sql_lines = filter( lambda x: not(x in ('','\r') or x[:2] in ('--','/*')), sql_lines) #generate the web2py code from the create statement web2py_table_code = '' table_name = re.search( 'CREATE TABLE .(\S+). \(', sql_lines[0]).group(1) fields = [] for line in sql_lines[1:-1]: if re.search('KEY', line) or re.search('PRIMARY', line) or re.search(' ID', line) or line.startswith(')'): continue hit = re.search('(\S+)\s+(\S+)(,| )( .*)?', line) if hit is not None: name, d_type = hit.group(1), hit.group(2) d_type = re.sub(r'(\w+)\(.*', r'\1', d_type) name = re.sub('`', '', name) web2py_table_code += "\n Field('%s','%s')," % ( name, data_type_map[d_type]) web2py_table_code = "legacy_db.define_table('%s',%s\n migrate=False)" % (table_name, web2py_table_code) legacy_db_table_web2py_code.append(web2py_table_code) #---------------------------------------- #write the legacy db to file legacy_db_web2py_code = connection_string + "\n\n" legacy_db_web2py_code += "\n\n#--------\n".join( legacy_db_table_web2py_code) return legacy_db_web2py_code regex = re.compile('(.*):(.*)@((.*)/)?(.*)') if len(sys.argv) < 2 or not regex.match(sys.argv[1]): print 'USAGE:\n\n extract_mysql_models.py username:password@[host/]data_basename\n\n' else: m = regex.match(sys.argv[1]) username = m.group(1) password = m.group(2) host = m.group(4) or 'localhost' db_name = m.group(5) print mysql(database_name = db_name, username = username, password = password, host = host)