Pyodbc:将pickled Python模型插入MS SQL Server时出错

Pyodbc:将pickled Python模型插入MS SQL Server时出错,python,sql-server,pickle,pyodbc,Python,Sql Server,Pickle,Pyodbc,我们已经尝试解决这个问题一段时间了,但是遇到了很多问题。想知道以前有没有人见过这个 我正在尝试用Pythonpickle一个简单的随机森林分类器(sklearn),并使用pyodbc将其保存到MS SQL Server数据库中。特别是,我使用的是UPDATE语句,因为我正在更新以前训练过的模型 以下是我使用的查询: RF_serialized = pickle.dumps(RF) RF_serialized_ins = str(RF_serialized)[1 : ] # doing this

我们已经尝试解决这个问题一段时间了,但是遇到了很多问题。想知道以前有没有人见过这个

我正在尝试用Python
pickle
一个简单的随机森林分类器(sklearn),并使用
pyodbc
将其保存到MS SQL Server数据库中。特别是,我使用的是
UPDATE
语句,因为我正在更新以前训练过的模型

以下是我使用的查询:

RF_serialized = pickle.dumps(RF)

RF_serialized_ins = str(RF_serialized)[1 : ] # doing this to cut off the leading 'b' from 
                                             # Python's byte data, per suggestions from other answers

q = "UPDATE table \
    SET serializedModel = CONVERT(VARBINARY(MAX), {}) \
    WHERE IDa = {} AND \
            IDb = {} AND \
            IDc = {}".format(RF_serialized_ins, "x", "y", "z")
但是,我不断收到以下非特定类型的错误:

pyodbc.ProgrammingError: ('42000', '[42000] [Microsoft][ODBC Driver 17 for SQL Server]Syntax error, permission violation, or other nonspecific error (0) (SQLExecDirectW)')
以前有人碰到过这个吗?我确信ID和筛选器是正确的,等等。目标列的数据类型是
VARBINARY(MAX)
。一个想法是:腌制的物体太大了吗?对象的大小:

print("Type of python object:", type(RF_serialized))
print("The size of the pickled RF model is:", RF_serialized.__sizeof__())
python对象的类型: 酸洗RF型号的尺寸为:5487942
以下是最终奏效的方法(感谢@Gord Thompson让我朝着正确的方向前进):

  • 使用转义参数化——根据
    pyodbc
    标准——而不是Python的
    .format()
    。我们最终将查询更改为以下内容:
  • 使用
    CONVERT(uniqueidentifier,?)
    而不是尝试为字符串输入特殊字符(例如
    \'
    ),因为SQL Server将GUID/唯一标识符视为数据类型
  • 在运行测试/故障排除时,我有两个额外的查询,我认为其中一个上有一个额外的
    .execute()
    ,这完全搞乱了我实际上试图修复的查询

  • 尝试使用适当的参数化查询,而不是动态SQL(
    .format
    )。这很有效-还进行了一些其他更改!我要写一个答案,因为看起来其他几个人也有类似的问题。谢谢
    Type of python object: <class 'bytes'>
    The size of the pickled RF model is: 5487942
    
    q = "UPDATE table \
        SET serializedModel = CONVERT(VARBINARY(MAX), ?) \
        WHERE IDa = CONVERT(uniqueidentifier, ?) AND \
                IDb = CONVERT(uniqueidentifier, ?) AND \
                IDc = CONVERT(uniqueidentifier, ?)"
    
    args = (RF_serialized,
            "x",
            "y",
            "z")
    
    cursor.execute(q, args)
    cnxn.commit()