【问题标题】:manage.py inspectdb and enumsmanage.py 检查数据库和枚举
【发布时间】:2012-04-24 18:46:42
【问题描述】:

A 中有很多带有枚举的表和字段。

是否有能力检查来自 MySQL 的枚举,例如 transit enum('yes','no') default 'no'?我明白了,默认情况下它不起作用。

我也有一个错误的字符长度定义:ipaddr varchar(15) NOT NULL default '', -> ipaddr = models.CharField(max_length=45)

【问题讨论】:

    标签: mysql django inspectdb


    【解决方案1】:

    这个操作似乎没有默认方法,或者我的问题太愚蠢了,无法回答。所以,我做了我自己的自行车:) 看起来该代码有效,但我没有很好地测试它。

    #!/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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-02
      • 2013-03-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多