似乎有此操作沒有默認方法,或我的問題太愚蠢了anwsering。所以,我做了我自己的自行車:) 它看起來像代碼的作品,但我沒有很好地測試。
#!/usr/bin/python
import re, MySQLdb
from MySQLdb import cursors
from settings import DATABASES
DB_SETUP = {
'host': DATABASES['default']['HOST'] or 'localhost',
'user': DATABASES['default']['USER'] or 'root',
'passwd': DATABASES['default']['PASSWORD'] or 'None',
'db': DATABASES['default']['NAME'] or 'mysql',
'charset': 'utf8',
}
db = MySQLdb.connect(cursorclass=cursors.DictCursor, **DB_SETUP)
cursor = db.cursor()
def max_len(str):
return max([ len(i.strip().replace("'", '')) for i in str.split(',') ])
def get_enum_tuple(string):
return tuple((i.strip().replace("'", ''), i.strip().replace("'", '')) for i in string.split(','))
patterns = {
re.compile(r'enum\((?P<choices>[\'|\w|,*|\s*]+)\)', re.IGNORECASE):
'models.CharField',
re.compile(r'varchar\((?P<max_length>\d+)\)', re.IGNORECASE):
'models.CharField',
re.compile(r'char\((?P<max_length>\d+)\)', re.IGNORECASE):
'models.CharField',
re.compile(r'int\((?P<max_length>\d+)\)', re.IGNORECASE):
'models.IntegerField',
re.compile(r'tinyint\((?P<max_length>\d+)\)', re.IGNORECASE):
'models.IntegerField',
re.compile(r'datetime', re.IGNORECASE):
'models.DateTimeField',
}
def table_classname(table):
words = [ w.capitalize() for w in table.split('_') ]
return ''.join(words)
cursor.execute('SHOW TABLES')
for table in [ i.values()[0] for i in cursor.fetchall() ]:
cursor.execute('DESCRIBE `%s`' % table)
class_model = []
for row in cursor.fetchall():
args = []
if row['Null'] == 'YES': args.append('blank=True')
if row['Default']: args.append("default='%s'" % row['Default'])
if row['Key'] == 'PRI': args.append('primary_key=True')
if row['Key'] == 'UNI': args.append('unique=True')
if '-' in row['Field']:
args.append("db_column='%s'" % row['Field'])
row['Field'] = row['Field'].replace('-', '_')
field_type = None
for pat in patterns:
m = pat.match(row['Type'])
if m:
d = m.groupdict()
if 'choices' in d:
args.append('max_length=%s' % max_len(d['choices']))
args.append('choices=%s' % str(get_enum_tuple(d['choices'])))
del d['choices']
if d:
for k in d:
args.append('%s=%s' % (k, d[k]))
field_type = patterns[pat]
break
args = ', '.join(args)
class_model.append('{field} = {field_type}({args})'.format(field=row['Field'], field_type=field_type, args=args))
print 'class %s(models.Model):' % table_classname(table)
for s in class_model:
print '\t%s' % s
print '\n\tclass Meta:'
print "\t\tdb_table = '%s'\n" % table