A 中有很多带有枚举的表和字段。
是否有能力从 MySQL 中检查枚举transit enum('yes','no') default 'no'
?我明白了,默认情况下它不起作用。
我也有一个错误的字符长度定义:ipaddr varchar(15) NOT NULL default '',
-> ipaddr = models.CharField(max_length=45)
似乎此操作没有默认方法,或者我的问题太愚蠢而无法回答。所以,我做了自己的自行车 :) 看起来该代码有效,但我没有很好地测试它。
#!/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