SQL Server机器学习服务Python客户端远程执行脚本报unknown opcode错误
故障现象
测试Python数据科学客户端与SQL Server Machine Learning Services远程连通性时,rx_exec远程调用函数返回SystemError: unknown opcode错误,报错堆栈指向被传输函数内的导入语句行,但相同代码逻辑在SQL Server本地直接运行Python脚本时可正常执行。
复现脚本
def send_this_func_to_sql(): from revoscalepy import RxSqlServerData, rx_import from pandas.tools.plotting import scatter_matrix import matplotlib.pyplot as plt import io # 注意该函数内变量作用域为SQL Server端的Python运行时 connection_string = "Driver=SQL Server;Server=localhost\instance02;Database=testmlsiris;Trusted_Connection=Yes;" # 指定查询并加载到pandas数据框df sql_query = RxSqlServerData(connection_string=connection_string, sql_query = "select * from iris_data") df = rx_import(sql_query) scatter_matrix(df) # 返回散点矩阵图的字节流 buf = io.BytesIO() plt.savefig(buf, format="png") buf.seek(0) return buf.getvalue() new_db_name = "testmlsiris" connection_string = "driver={sql server};server=sqlrzs\instance02;database=%s;trusted_connection=yes;" from revoscalepy import RxInSqlServer, rx_exec # 创建连接到SQL Server的远程计算上下文 sql_compute_context = RxInSqlServer(connection_string=connection_string%new_db_name) # 调用rx_exec将函数发送到SQL Server端执行 image = rx_exec(send_this_func_to_sql, compute_context=sql_compute_context)[0]
报错堆栈
connection_string: "driver={sql server};server=sqlrzs\instance02;database=testmlsiris;trusted_connection=yes;" num_tasks: 1 execution_timeout_seconds: 0 wait: True console_output: False auto_cleanup: True packages_to_load: [] description: "sqlserver" version: "1.0" XXX lineno: 2, opcode: 0 Traceback (most recent call last): File "<string>", line 3, in <module> File "E:\SQL\MSSQL15.INSTANCE02\PYTHON_SERVICES\lib\site-packages\revoscalepy\computecontext\RxInSqlServer.py", line 664, in rx_sql_satellite_pool_call exec(inputfile.read()) File "<string>", line 34, in <module> File "E:\SQL\MSSQL15.INSTANCE02\PYTHON_SERVICES\lib\site-packages\revoscalepy\computecontext\RxInSqlServer.py", line 886, in rx_remote_call results = rx_resumeexecution(state_file = inputfile, patched_server_name=args["hostname"]) File "E:\SQL\MSSQL15.INSTANCE02\PYTHON_SERVICES\lib\site-packages\revoscalepy\computecontext\RxInSqlServer.py", line 135, in rx_resumeexecution return _state["function"](**_state["args"]) File "C:\Users\username\sendtosql.py", line 2, in send_this_func_to_sql SystemError: unknown opcode ====== sqlrzs ( process 0 ) has started run at 2022-06-29 13:47:04 W. Europe Daylight Time ====== {'local_state': {}, 'args': {}, 'function': <function send_this_func_to_sql at 0x0000020F5810F1E0>}
故障原因
- 核心诱因是客户端与服务端Python运行时版本不兼容:
rx_exec的远程执行逻辑会将本地定义的Python函数序列化为字节码后,传输到SQL Server内置的Python运行时加载执行。如果客户端本地使用的Python大版本高于SQL Server内置的Python版本,高版本生成的字节码会包含低版本解释器无法识别的操作码(opcode),就会抛出该错误。 - 报错定位到导入语句属于表象:服务端解释器加载函数字节码时,只要遇到无法识别的opcode就会终止执行,错误位置会默认标记为函数内第一个可执行语句行,和导入逻辑本身没有关系,这也是相同代码在SQL Server本地运行无异常的原因——本地执行时使用的是和代码编译版本匹配的解释器,不存在字节码兼容问题。
解决方法
- 先确认SQL Server实例内置的Python版本:SQL Server 2017内置Python 3.5,SQL Server 2019内置Python 3.7,可通过SQL Server执行外部脚本查询版本号做最终确认。
- 将客户端发起远程调用的Python环境版本,调整为与服务端内置Python完全一致的大版本,禁止使用高于服务端版本的Python环境发起
rx_exec远程调用。 - 同步检查客户端安装的
revoscalepy组件版本,保证其与SQL Server端安装的Machine Learning Services组件版本一致,避免组件版本差带来的序列化兼容问题。
内容的提问来源于stack exchange,提问作者fnjo
相关产品推荐
相关产品推荐

