Python Mysqldb 为位值返回 '\x01'

Posted

技术标签:

【中文标题】Python Mysqldb 为位值返回 \'\\x01\'【英文标题】:Python Mysqldb returning '\x01' for bit valuesPython Mysqldb 为位值返回 '\x01' 【发布时间】:2013-10-15 20:59:58 【问题描述】:

我将 mysqldb 与 Python(2.7) 一起使用,以从具有字符集 latin1 的 Mysql 数据库中返回一堆值。

mysql 数据库在返回时具有 bit(1) 类型的值,它们看起来像这样 '\x01'

十进制值返回如下 Decimal('0E-8')

其余的值和类型都很好。

示例数据库结果集:

'test': '\x01', 'currency': u'bla', 'balance': Decimal('0E-8'), 'first': u'John'

这是我连接到数据库的方式: self.con = MySQLdb.connect(host = conn['host'], user = conn['user'], passwd=conn['passwd'], db=conn['db'], charset=conn['charset '],port = int(conn['port']) if 'port' in conn else 3306)

我希望将 bit(1) 值返回为 True 或 False。 我环顾四周,我认为可能是做 MySQLdb.converters.conversions 但我不知道如何实现这一点。任何想法都会很棒。 谢谢

而且我无权更改数据库中的类型。

【问题讨论】:

【参考方案1】:

在与 MySQL 内部开发人员交谈时,他们都说 BIT 数据类型已损坏并且充满了错误。

示例:Why you should not use BIT columns in MySQL,由 High Performance MySQL 的合著者 Baron Schwartz 撰写。

所以我建议使用 TINYINT 并存储 0 或 1 来表示布尔值。您不会浪费任何空间,因为 BIT 列的大小无论如何都会四舍五入到最接近的整个字节。

MySQL 甚至还有一个数据类型别名 BOOL。当你使用它时,它被映射到TINYINT(1)(虽然 1 不影响任何东西)。


如果您无法更改数据类型,则可以在 SQL 查询中将其映射为整数:

MySQL 使用 1 或 0 作为布尔值,所以你可以这样做:

SELECT (test=B'1') AS test, currency, balance, first FROM ...

或者你可以更详细:

SELECT IF(test=B'1', 1, 0) AS test, currency, balance, first FROM ...

或者您可以完全兼容 SQL:

SELECT CASE test=B'1' WHEN true THEN 1 ELSE 0 END AS test, currency, balance, first FROM ...

【讨论】:

感谢您的回复,但很遗憾,我无法在我的域之外更改他数据库中的类型。【参考方案2】:

想通了: 所以只好在Mysqldb包里挖一点。

orig_conv = MySQLdb.converters.conversions
#Adding support for bit data type
orig_conv[FIELD_TYPE.BIT] = bool

passing this into my connection.
MySQLdb.connect(conv=orig_conv)

FIELD_TYPE可以在MySQLdb.constants中找到,可以这样导入

from MySQLdb.constants import FIELD_TYPE

【讨论】:

实际上这也引起了问题 - 所有行都返回 true,我们没有收到运行时错误但数据错误:s 这个答案是错误的,看下面“RhysC”的正确答案【参考方案3】:

试试:

orig_conv = MySQLdb.converters.conversions
#Adding support for bit data type
orig_conv[FIELD_TYPE.BIT] = lambda data: data == '\x01'

passing this into my connection.
MySQLdb.connect(conv=orig_conv)

使用“orig_conv[FIELD_TYPE.BIT] = bool”对我来说一切都是真的

【讨论】:

这是实际答案!当前接受的答案是错误的,无论数据库中的实际值如何,所有 BIT 字段都为 True。 这也适用于 pymysql。您可以使用“orig_conv[FIELD_TYPE.BIT] = ord”进行简化。 大家好...一些想法,以便将此解决方案适用于 google cloud python sdk for Mysql?【参考方案4】:
from pymysql import converters
converions = converters.conversions
converions[pymysql.FIELD_TYPE.BIT] = lambda x: '0' if x == '\x00' else '1'
db = pymysql.connect(mysql_host, mysql_user, mysql_password, mysql_db, 3306,charset='utf8',conv=converions)

【讨论】:

以上是关于Python Mysqldb 为位值返回 '\x01'的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SqlDataReader 获取位值并将其转换为布尔值?

在python中将字节转换为位

在 Python 中将 MySQLdb 返回从元组转换为字符串

使用python做登陆程序,在数据库中查找用户名和密码是不是正确?

Python MySQLdb 意外行为(?)

Python MySQLdb 将双引号改为单引号