Docker容器运行Python脚本时ODBC驱动文件缺失问题排查
在Docker容器中运行Python脚本sharepoint_to_json.py(用于将Excel(.xlsx)转换为JSON,需连接SQL Server)时出现错误,容器已安装msodbcsql17驱动,其他脚本可正常连接数据库,但该脚本报错:
Ocorreu um erro ao processar o arquivo Excel: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib '/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.9.so.1.1' : file not found (0) (SQLDriverConnect)")
Dockerfile相关内容:
FROM python:3.12 RUN apt-get update && apt-get install -y \ curl \ gnupg2 \ apt-transport-https \ unixodbc \ unixodbc-dev \ python3-distutils \ build-essential \ && curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - \ && curl https://packages.microsoft.com/config/debian/10/prod.list > /etc/apt/sources.list.d/mssql-release.list \ && apt-get update && ACCEPT_EULA=Y apt-get install -y msodbcsql17 # Set the working directory in the container WORKDIR /app # Upgrade pip, setuptools, wheel to ensure the latest versions RUN pip install --upgrade pip setuptools wheel # Copy the requirements.txt file COPY requirements.txt . # Install the dependencies RUN pip install -r requirements.txt # Copy the project files COPY . /app/ # Expose port 8000 EXPOSE 8000 # Set environment variable to indicate that Django is running in the container ENV PYTHONUNBUFFERED 1 # Default command CMD ["sh", "-c", "python wait_for_db.py && python manage.py makemigrations && python manage.py migrate && python test_connection.py && python sharepoint_to_json.py && python manage.py runserver 0.0.0.0:8000"]
已验证msodbcsql17驱动安装,检查/opt/microsoft/msodbcsql17/lib64/路径发现libmsodbcsql-17.9.so.1.1文件不存在,且odbcinst.ini配置无误。
疑问:
- 为何其他脚本可正常使用驱动,唯独
sharepoint_to_json.py报错? - 如何修复Docker环境中的文件缺失错误?
- 有没有更优的方法验证容器内ODBC驱动是否正确安装并被识别?
1. 仅目标脚本报错的原因
- 硬编码驱动路径:
sharepoint_to_json.py的数据库连接配置里可能直接写死了libmsodbcsql-17.9.so.1.1这个特定版本的文件路径,而其他脚本用的是驱动名称(比如ODBC Driver 17 for SQL Server),unixODBC会自动匹配当前安装的驱动文件,不会依赖固定版本路径。 - 依赖版本差异:该脚本可能安装了与其他脚本不同版本的数据库连接库(比如
pyodbc),不同版本的库对驱动路径的解析逻辑有差异,导致找不到指定文件。
2. 修复文件缺失错误的方法
方法一:修正脚本的驱动指定方式
打开sharepoint_to_json.py,找到数据库连接字符串,把硬编码的文件路径替换为驱动名称:
# 原错误写法示例 conn = pyodbc.connect('DRIVER=/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.9.so.1.1;SERVER=xxx;...') # 修改为 conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=xxx;...')
方法二:安装指定版本的驱动
如果必须使用17.9版本,修改Dockerfile中安装驱动的命令,指定版本号:
# 替换原安装msodbcsql17的行 RUN ACCEPT_EULA=Y apt-get install -y msodbcsql17=17.9.1.1-1
注:版本号需匹配Debian 10软件源,可先在容器内执行apt-cache show msodbcsql17查看可用版本。
方法三:创建软链接匹配缺失路径
如果当前安装的是其他版本驱动(比如17.10.x),可以创建软链接指向实际存在的文件:
# 在安装驱动后添加以下命令 RUN ln -s /opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.*.so.1.1 /opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.9.so.1.1
或者进入运行中的容器临时执行:
docker exec -it <容器ID> ln -s /opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.*.so.1.1 /opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.9.so.1.1
3. 验证ODBC驱动的最优方法
- 查看驱动配置:执行
odbcinst -j查看unixODBC的配置路径,再查看odbcinst.ini内容确认驱动注册情况:
odbcinst -j cat /etc/odbcinst.ini
正常输出会包含ODBC Driver 17 for SQL Server及其对应的驱动文件路径。
- 用isql测试连接:先安装
unixodbc-bin工具,再直接测试SQL Server连接:
# 在Dockerfile中添加安装命令 RUN apt-get install -y unixodbc-bin
执行测试命令:
# 用DSN测试 isql -v <你的DSN名称> <用户名> <密码> # 直接用驱动名称测试 isql -v "DRIVER={ODBC Driver 17 for SQL Server};SERVER=<服务器地址>;DATABASE=<数据库名>;" <用户名> <密码>
- 极简Python测试脚本:编写无业务逻辑的测试脚本,用驱动名称连接数据库:
import pyodbc try: conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=xxx;UID=xxx;PWD=xxx') print("驱动连接成功") conn.close() except Exception as e: print(f"连接失败: {e}")
内容的提问来源于stack exchange,提问作者Giovanna Lino

