Back to home

Fix Demical is not JSON serializable

问题

Mysql对于小数均会处理为DECIMAL类型,而mysql-connector-python模块则会按照其字段类型直接映射为Python中的Decimal类型对象。

解决

下面直接给出实现,由于是在特定版本下的实现(直接取自Pip的当前最新版),具体API可能有所不同。

$ pip freeze | grep mysql
mysql-connector-python==1.0.12

文档中已经给出了可以指定类型转换对象。类库已经实现了一个转换器,我们重写关键方法即可。 “ from mysql.conversion import MySQLConverter

class JSONableMYSQLConverter(MySQLConverter): def _DECIMAL_to_python(self, v, desc=None): ”“” Returns v as a decimal.Decimal. “”“ return float(v) _NEWDECIMAL_to_python = _DECIMAL_to_python ”

在创建连接时指定我们实现的转换器,由于新版尚未提交到Pip中,无法按照文档中直接将转换器已构造参数形式指定,翻阅源码后,发现set_converter_class方法可以实现此功能。

with closing(mysql_conner.connect(**config.conn)) as cnx:
    cnx.set_converter_class(JSONableMYSQLConverter)
    with closing(cnx.cursor()) as cursor:
        cursor.execute("""SELECT 123/321;""")
        print list(cursor)

后记

实现自定义的类型的方案有许多,你也可以通过json.dumps指定defaults参数,或者实现一个json.JSONEncoder.
为了尽早使得数据可用,以及接口限制(逻辑代码没有接触json.dumps,不能自定义JSON序列化规则),所以采用这种方案。