【问题标题】: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 但我不知道如何实现这一点。任何想法都会很棒。 谢谢

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

【问题讨论】:

    标签: python mysql python-2.7 mysql-python


    【解决方案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)
    

    【讨论】:

      猜你喜欢
      • 2019-10-15
      • 1970-01-01
      • 2011-11-20
      • 2021-06-08
      • 1970-01-01
      • 2012-03-30
      • 1970-01-01
      • 2013-06-05
      • 2013-01-29
      相关资源
      最近更新 更多