MySql Python Connector 将 INT 转为 int64,但不会再转回去?

MySql Python Connector turns INT into int64, but not back again?

我正在使用 MySQL Python 连接器来操作数据库,但是当我的查询涉及 INT 数据库类型时 运行 出现问题。当 MySQL 从数据库中检索 INT 列时,它似乎转换为 Python int64。这很好,除了它不会将其转换回 为可用的 MySql 类型。

这是一个简化的例子:

这是我的 MySql table 'test' 架构,ID 为 INT 数据类型:

我的 Python 代码如下。第二次执行(UPDATE 查询)失败,出现以下异常:

Exception Thrown: Failed processing format-parameters; Python 'int64' cannot be converted to a MySQL type

如果我使用 int(firstId) 显式转换 'firstId' 参数(报告为类型 ),代码运行成功:。我可能会天真地假设,如果 MySql 在一个方向上管理转换,它会在另一个方向上管理它。实际上,我不一定知道我从实际查询中获得的类型(我正在使用 Python ...我不必知道)。这是否意味着我必须在 运行 MySql 查询之前对所有 Python 变量进行类型检查?

我尝试将 table 列数据类型从 INT 更改为 BIGINT(64 位 INT),但我遇到了相同的转换错误。我正在使用的 MySql 连接器包 (mysql-connector-python 8.0.23) 上可能存在 32 位/64 位不匹配吗?

import mysql.connector as msc
import pandas as pd

def main():
    dbConn = msc.connect(user='********', password='********',
                              host='127.0.0.1',
                              database='********')
    #Open a cursor
    cursor = dbConn.cursor()
    #Find Id of given name
    cursor.execute('SELECT * from test WHERE Name = %s',['Hector'])
    headers = cursor.column_names
    queryVals = list()

    for row in cursor:
            queryVals.append(row)
        
    cursor.close()   
    dfQueryResult = pd.DataFrame(queryVals,columns = headers)
    
    print(dfQueryResult)

    #Change name 
    firstId = dfQueryResult['Id'].iloc[0]
    print('firstId is of type: ',type(firstId))

    cursor = dbConn.cursor()
    cursor.execute('UPDATE test SET Name =%s WHERE Id =%s',['Graham',firstId]) #This line gives the error
    print(cursor.rowcount,' rows updated')
        
    cursor.close()   

    dbConn.commit()
    dbConn.close()

main()

首先,感谢@NonoLondon 的评论和调查工作。

A pandas Dataframe 使用 NumPy 类型存储数字。在这种情况下,DataFrame 构造函数从 MySql return 中获取 Python 'int' 并将其转换为 Numpy.int64 对象。当 MySql 再次使用此变量时,连接器无法将 Numpy.int64 转换回直接 Python 'int'.

从其他 SO 文章中,我发现了适用于所有 Numpy 数据类型的 item() 方法,它可以转换为基础 Python 类型。由于所有 Numpy 数据类型都派生自基础 class Numpy.generic,因此每当我从 DataFrames 中提取变量时,我现在都使用以下实用函数:

import numpy as np

def pyTypeFromNp(val):
    if isinstance(val,np.generic):
        return val.item()

    return val

因此修改后的行现在是:

firstId = pyTypeFromNp(dfQueryResult['Id'].iloc[0])

并且代码按预期运行