121 lines
4.7 KiB
Python
121 lines
4.7 KiB
Python
|
'''
|
||
|
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)
|