2012-04-24 84 views
0

有很多表和字段在他們的枚舉。manage.py inspectdb和枚舉

是否有能力檢查MySQL的枚舉類似transit enum('yes','no') default 'no'?我明白,默認情況下它不起作用。

也對我有錯誤的字符長度的定義:ipaddr varchar(15) NOT NULL default '', - > IPADDR = models.CharField(MAX_LENGTH = 45)

回答

0

似乎有此操作沒有默認方法,或我的問題太愚蠢了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