cursor.description中"type_code"与数据库字段类型的对应关系

5 投票
3 回答
5064 浏览
提问于 2025-04-17 04:34

我在用MySQL作为后台,想要通过游标描述中的type_code来确定表字段的类型...

我得到的是一堆不同的数字...通过把我的表和type_code值进行比较,我可以手动整理出一套对应关系...但我发现的类型比我在Python书(Beazley)中记录的类型要多得多,比如STRING、BINARY、NUMBER、DATETIME、ROWID。

我猜测可能还有其他的type_code,比如DECIMAL、UNSIGNED INT等等...但我很惊讶在这里或者网上找不到相关的信息。

顺便说一下,我想做的是自动化这个过程,也就是说,输入(比如在一个连接到MySQL表的图形界面网格中)能够确定该列期望的数据类型,并解析和检查这些数据,以判断这些值是否合法。

3 个回答

2

如果你在使用 MySQLdb,那么 MySQLdb.constants.FIELD_TYPE 这个模块里包含了每种字段类型的常量。

>>> print dir(MySQLdb.constants.FIELD_TYPE)
['BIT', 'BLOB', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'DOUBLE', 'ENUM', 
 'FLOAT', 'GEOMETRY', 'INT24', 'INTERVAL', 'LONG', 'LONGLONG', 'LONG_BLOB', 
 'MEDIUM_BLOB', 'NEWDATE', 'NEWDECIMAL', 'NULL', 'SET', 'SHORT', 'STRING', 
 'TIME', 'TIMESTAMP', 'TINY', 'TINY_BLOB', 'VARCHAR', 'VAR_STRING', 'YEAR',
 '__builtins__', '__doc__', '__file__', '__name__', '__package__']

比如,类型代码 5 表示这是一个 MySQL 的双精度浮点数。

>>> MySQLdb.constants.FIELD_TYPE.DOUBLE 
5

这个模块的详细信息可以在 文档 中找到。

4

如果你想知道怎么把ID和描述对应起来,可以参考这个字典:

>>> ft = MySQLdb.constants.FIELD_TYPE
>>> d = {getattr(ft, k): k for k in dir(ft) if not k.startswith('_')}
>>> d
{0: 'DECIMAL',
 1: 'TINY',
 2: 'SHORT',
 3: 'LONG',
 4: 'FLOAT',
 5: 'DOUBLE',
 6: 'NULL',
 7: 'TIMESTAMP',
 8: 'LONGLONG',
 9: 'INT24',
 10: 'DATE',
 11: 'TIME',
 12: 'DATETIME',
 13: 'YEAR',
 14: 'NEWDATE',
 15: 'VARCHAR',
 16: 'BIT',
 246: 'NEWDECIMAL',
 247: 'INTERVAL',
 248: 'SET',
 249: 'TINY_BLOB',
 250: 'MEDIUM_BLOB',
 251: 'LONG_BLOB',
 252: 'BLOB',
 253: 'VAR_STRING',
 254: 'STRING',
 255: 'GEOMETRY'}
3

你书里提到的基本类型代码是根据DB-API规范来定义的。

类型代码必须和下面定义的某个类型对象相等。

这里的关键是,可能会有多个不同的类型代码,它们都能和同一个类型对象相等。

>>> MySQLdb.constants.FIELD_TYPE.TIMESTAMP
7
>>> MySQLdb.constants.FIELD_TYPE.DATETIME
12
>>> MySQLdb.constants.FIELD_TYPE.TIMESTAMP==MySQLdb.DATETIME
True
>>> MySQLdb.constants.FIELD_TYPE.DATETIME==MySQLdb.DATETIME
True
>>> MySQLdb.DATETIME
DBAPISet([12, 7])

这种“魔法”的实现方式在DB-API规范中关于DBAPITypeObject的说明里有提到。更传统的接口可能会通过子类来实现这一点……

这使得MySQLdb能够提供比仅仅判断某列是否为日期时间类型更丰富的信息,同时也能简单地测试一个值是字符串还是数字。

当然,如果你直接和MySQLdb.constants.FIELD_TYPE类型进行比较,那你就依赖于MySQLdb的功能,这些功能可能无法在其他数据库上使用。

撰写回答