【问题标题】:pymysql connection select query and fetchall return tuple that has byte literals like b'25.00' rather than strings like '25.00'pymysql 连接选择查询和 fetchall 返回具有像 b'25.00' 这样的字节文字而不是像 '25.00' 这样的字符串的元组
【发布时间】:2015-03-07 10:44:57
【问题描述】:

我有一个python script,它只在使用pymysql 连接到我在Windows 8.1 上具有MySQL 5.6database 的本地测试机器时运行良好。 Select query / fetchal() 返回像 ('1', '2015-01-02 23:11:19', '25.00') 这样的元组。

但是,当我使用稍微修改的相同脚本以包含到在 Linux 服务器上运行的远程 MySQL 5.0.96 生产数据库的第二个连接时,它会返回 tuples,例如 (b'1', b'2015- 01-02 23:11:19', b'25.00') 并且脚本无法正确运行,因为匹配条件和使用返回元组的查询失败。

知道为什么,我怎样才能让它返回tuples,其列值没有“b”前缀?

【问题讨论】:

  • 你在两个系统上是否有相同的python版本,或者在一个系统上有一个python 2,另一个在另一个系统上有一个python3?
  • 我使用 python 3.4 在同一台 win8.1 机器上运行这两个脚本。发生变化的是与 GoDaddy 上具有旧 MySQL 版本的远程 MySQL 数据库的连接。

标签: python mysql pymysql fetchall


【解决方案1】:

我通过以下解决方法解决了这个问题。它涉及处理从远程数据库列返回的字节文字,如下面的示例所示,我创建该示例来解释答案。

conn = pymysql.connect(host=myHost, port=myPort, user=myUser, passwd=myPassword, database=myDatabase, charset="utf8")
cur = conn.cursor()

theDateTime = re.sub( r' ', '-', str(datetime.now()))
theDateTime = theDateTime[0:10] + " " + theDateTime[11:19]

productName = 'abc'
myMaxPrice = 100.0

try:
    # The below query to the remote database returned tuples like (b'1', b'2015-01-02 23:11:19', b'25.00') for MySQL DB tableA columns: ID, date_changed, price
    query = "SELECT IFNULL(ID,''), IFNULL(date_changed,''), IFNULL(price, '') FROM tableA WHERE product = '" + productName + "';"   
    cur.execute(query)
    for r in cur.fetchall():
        # Given the returned result tuple r[] from the remote DB included byte literals instead of strings, I had to encode the '' strings in the condition below to make them byte literals
        # However, I did not have to encode floats like mMaxyPrice and float(r[2]) as they were not a string; float calculations were working fine, even though the returned float values were also byte literals within the tuple
        if not r[1] and float(r[2]) >= myMaxPrice: 
            #Had to encode and then decode r[0] below due to the ID column value r[0] coming back from the remote DB query / fetchall() as a byte literal with a "b" prefix
            query = "UPDATE tableA SET date_changed = '" + theDateTime + "', price = " + str(myMaxPrice) + " WHERE ID = " + r[0].decode(encoding='utf-8') + ";"  
            cur.execute(query)
            conn.commit()
except pymysql.Error as e:
    try:
        print("\nMySQL Error {0}: {1}\n".format(e.args[0], e.args[1]))
    except IndexError:
        print("\nMySQL Index Error: {0}\n".format(str(e)))
    print("\nThere was a problem reading info from the remote database!!!\n") 

感谢 m170897017 指出这些是字节文字,并感谢 Neha Shukla 帮助澄清。尽管我仍然有兴趣弄清楚为什么远程数据库返回字节文字,而不是本地数据库返回的字符串。我需要使用某种编码来连接到远程数据库吗?如何使用?是远程数据库中使用的旧版本的 MySQL 导致的吗?这是Linux远程与Windows本地的区别吗?或者是引入字节文字的 fetchall() 函数?如果有人知道,请提供它以帮助我进一步理解这一点。

【讨论】:

    【解决方案2】:

    b 前缀表示 Python3 中的字节文字。尝试将其转换为字符串。

    ...
    res = (b'1', b'2015-01-02 23:11:19', b'25.00')
    new_res = []
    for i in res:
        new_res.append(i.decode(encoding='utf-8'))
    
    new_res = tuple(new_res)
    ...
    

    【讨论】:

    • 试过了,这一行:new_res.append(i.decode('utf-8')) 给出错误:AttributeError: 'str' object has no attribute 'decode'
    • @MichaelD。从我这边看来还可以。尝试另一种方式。检查我的更新。
    • 我将 Eclipse 与 Pydev 一起使用,它抱怨:未定义的变量:unicode。我需要导入一些东西吗?
    • @MichaelD。检查我的最新更新。告诉我它是否有效。由于我没有你的代码,我只能猜测解决方案...
    • 我尝试了最新的,但我仍然得到 AttributeError: 'str' object has no attribute 'decode' 这很奇怪,因为它告诉我它是一个 'str' 对象,但是当我尝试一个字符串时i.decode(encoding='utf-8') 上的替换函数,看看我是否可以摆脱“b”前缀,然后它抱怨它是一个字节对象!我怀疑这与远程机器连接的编码有关,因为我本地机器上的相同代码返回没有“b”前缀的字符串。如果我们能找出正确的连接编码,那么就不需要在代码中修复它了吗?
    猜你喜欢
    • 1970-01-01
    • 2011-06-30
    • 1970-01-01
    • 2011-09-11
    • 2012-09-18
    • 1970-01-01
    • 2015-06-21
    • 2012-03-25
    • 1970-01-01
    相关资源
    最近更新 更多