在腾讯云函数中使用Pandas报错`No module named 'numpy.core._multiarray_umath'`
本文分析了在腾讯云的WebIDE中安装Pandas及其依赖文件并部署到Serverless后引用时报错No module named 'numpy.core._multiarray_umath'
的原因,并给出了几个应对方法供参考。
一、问题
阿猪尝试在腾讯云的Serverless中创建一个Python项目,并在这个Python项目中导入Pandas模块。操作步骤如下:
1、创建一个新的Python项目
在Serverless的函数服务中依次点击“新建” - “从头开始”,各项配置均保持默认,然后点击“完成”按钮。
2、在WebIDE环境中生成依赖文件
在WebIDE的终端中输入如下命令:
1 | cd src # 假设当前位于初始位置(项目的根目录) |
3、在项目文件中引用Pandas
以下是一个简单的示例:
1 | # -*- coding: utf8 -*- |
4、部署
在WebIDE中点击“部署”按钮,将项目文件和依赖一起从WebIDE环境上传到Serverless中并完成部署。
5、测试
在WebIDE中点击“测试”按钮,报错如下:
{“errorCode”:1,”errorMessage”:”Traceback (most recent call last):\n File "/var/runtime/python39/bootstrap.py", line 133, in init_handler\n func_handler = get_func_handler(file.rsplit(".", 1)[0], func)\n File "/var/runtime/python39/bootstrap.py", line 159, in get_func_handler\n mod = imp.load_module(mname, *imp.find_module(mname))\n File "/var/lang/python39/lib/python3.9/imp.py", line 234, in load_module\n return load_source(name, filename, file)\n File "/var/lang/python39/lib/python3.9/imp.py", line 171, in load_source\n module = _load(spec)\n File "\u003cfrozen importlib._bootstrap\u003e", line 711, in _load\n File "\u003cfrozen importlib._bootstrap\u003e", line 680, in _load_unlocked\n File "\u003cfrozen importlib._bootstrap_external\u003e", line 850, in exec_module\n File "\u003cfrozen importlib._bootstrap\u003e", line 228, in _call_with_frames_removed\n File "/var/user/index.py", line 2, in \u003cmodule\u003e\n import pandas\n File "/var/user/pandas/init.py", line 16, in \u003cmodule\u003e\n raise ImportError(\nImportError: Unable to import required dependencies:\nnumpy: \n\nIMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!\n\nImporting the numpy C-extensions failed. This error can happen for\nmany reasons, often due to issues with your setup or how NumPy was\ninstalled.\n\nWe have compiled some common reasons and troubleshooting tips at:\n\n https://numpy.org/devdocs/user/troubleshooting-importerror.html\n\nPlease note and check the following:\n\n * The Python version is: Python3.9 from "/var/lang/python39/bin/python3"\n * The NumPy version is: "1.21.6"\n\nand make sure that they are the versions you expect.\nPlease carefully study the documentation linked above for further help.\n\nOriginal error was: No module named ‘numpy.core._multiarray_umath’\n”,”requestId”:”61e76551-3ea2-432d-a6d9-22e3f65f6161”,”statusCode”:443}
二、原因
阿猪认为问题的根源是WebIDE环境下生成的Numpy与Serverless实例中的环境不兼容。
首先,报错信息中提到的numpy.core._multiarray_umath
对应的文件路径为/numpy/core/_multiarray_umath.cpython-37m-x86_64-linux-gnu.so
(在Windows下则是PYD文件)。SO文件是Linux中编译后的二进制文件,此类文件可能因为编译环境的差异而存在兼容性问题的。结合这个SO文件的名称,阿猪猜测在WebIDE环境中生存的这个SO文件是适用于X86和X64架构Linux的Python3.7的,可能与Serverless实例的Python3.9不兼容。
其次,在WebIDE的终端执行pip --version
,返回结果如下:
pip 23.3.1 from /var/lang/python37/lib/python3.7/site-packages/pip (python 3.7)
可以看到实际运行的是Python3.7下的pip,这一方面进一步印证了前边的猜测,另一方面也说明阿猪之前直接使用pip命令安装Pandas的方法是错误的,没有考虑到多Python环境的差异。
进一步的,阿猪尝试修改之前的命令,指定Python3.9的pip来安装Pandas:
1 | python3.9 -m pip install pandas -t ./src |
但出乎意料的时,竟然返回了No module named 'pip._internal.operations.build'
的报错,也就是说Python3.9的pip无法正常运行。具体报错信息如下:
Traceback (most recent call last):
File “/var/lang/python39/lib/python3.9/runpy.py”, line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File “/var/lang/python39/lib/python3.9/runpy.py”, line 87, in _run_code
exec(code, run_globals)
File “/var/lang/python39/lib/python3.9/site-packages/pip/main.py”, line 31, in
sys.exit(_main())
File “/var/lang/python39/lib/python3.9/site-packages/pip/_internal/cli/main.py”, line 68, in main
command = create_command(cmd_name, isolated=(“–isolated” in cmd_args))
File “/var/lang/python39/lib/python3.9/site-packages/pip/_internal/commands/init.py”, line 109, in create_command
module = importlib.import_module(module_path)
File “/var/lang/python39/lib/python3.9/importlib/init.py”, line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File ““, line 1030, in _gcd_import
File ““, line 1007, in _find_and_load
File ““, line 986, in _find_and_load_unlocked
File ““, line 680, in _load_unlocked
File ““, line 850, in exec_module
File ““, line 228, in _call_with_frames_removed
File “/var/lang/python39/lib/python3.9/site-packages/pip/_internal/commands/install.py”, line 14, in
from pip._internal.cli.req_command import (
File “/var/lang/python39/lib/python3.9/site-packages/pip/_internal/cli/req_command.py”, line 21, in
from pip._internal.index.package_finder import PackageFinder
File “/var/lang/python39/lib/python3.9/site-packages/pip/_internal/index/package_finder.py”, line 32, in
from pip._internal.req import InstallRequirement
File “/var/lang/python39/lib/python3.9/site-packages/pip/_internal/req/init.py”, line 8, in
from .req_install import InstallRequirement
File “/var/lang/python39/lib/python3.9/site-packages/pip/_internal/req/req_install.py”, line 30, in
from pip._internal.operations.build.metadata import generate_metadata
ModuleNotFoundError: No module named ‘pip._internal.operations.build’
三、解决方法
1、将WebIDE中Python3.7里的pip文件复制到Python3.9
依次执行如下命令,将Python3.9中的pip删除,并使用Python3.7中的pip替代:
1 | rm -rf /var/lang/python39/lib/python3.9/site-packages/pip/ |
完成以上的命令后,就可以正常的使用Python3.9的pip安装Pandas了。
安装完成后,可以在WebIDE的终端中运行如下命令来测试,正常情况下会返回Numpy的版本号:
1 | python3.9 -c "import numpy; print(numpy.__version__)" # 假设当前位于项目的src目录下 |
2、为WebIDE的Python3.9重新安装pip
1 | curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && python3.9 get-pip.py --force-reinstall |
3、重新创建项目,将运行环境改为Python3.7或更低。
在函数服务中新建Python项目时,将运行环境修改为Python3.7或更低版本。
4、不使用WebIDE,使用其他Linux环境来生成依赖文件
请注意用来生成依赖文件的环境尽量与Serverless的环境保持一致,即 x86架构 + CentOS + Python3.9 。