You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过Azure容器部署的FastAPI在Azure App Service无法读取MySQL数据

问题分析与排查修复步骤

核心问题定位

从Docker日志的Can't open lib 'ODBC Driver 18 for SQL Server'错误,结合你提到的“本地已安装ODBC驱动可正常连接”,核心问题是Docker容器内未正确安装对应ODBC驱动,同时存在两个潜在的关键错误:


一、优先确认:数据库类型与驱动匹配

你开头提到是“Azure上MySQL数据库”,但连接代码使用的是ODBC Driver 18 for SQL Server(SQL Server专用驱动),这是完全不匹配的:

  • 若使用Azure MySQL:需改用MySQL专用驱动,比如mysql-connector-python(无需ODBC),或pyodbc配合MySQL ODBC 8.0 Driver
  • 若实际使用Azure SQL Server:驱动选择正确,但容器内安装步骤有误

二、针对Azure SQL Server的Docker驱动安装修复

如果确实是Azure SQL Server,按以下步骤修正Dockerfile:

1. 正确的驱动安装步骤(以Debian/Ubuntu基础镜像为例)

使用python:x-slim作为基础镜像时,需安装微软官方的ODBC驱动18,完整Dockerfile示例:

FROM python:3.11-slim

# 安装系统依赖与SQL Server ODBC驱动
RUN apt-get update && apt-get install -y --no-install-recommends \
    unixodbc \
    unixodbc-dev \
    curl \
    gnupg2 \
    && curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - \
    && curl https://packages.microsoft.com/config/debian/11/prod.list > /etc/apt/sources.list.d/mssql-release.list \
    && apt-get update \
    && ACCEPT_EULA=Y apt-get install -y msodbcsql18 \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# 设置工作目录与依赖安装
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir fastapi uvicorn pyodbc
COPY . .

# 启动FastAPI服务
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]

2. 验证容器内驱动是否安装成功

运行容器后,进入容器执行以下命令确认驱动存在:

# 查看已注册的ODBC驱动
odbcinst -j
# 检查驱动文件是否存在
ls /opt/mssql-tools/lib64/libmsodbcsql-18.so

3. 修正连接代码的驱动名称

Linux环境下ODBC驱动名称无需大括号,修改db.py:

driver= "ODBC Driver 18 for SQL Server"  # 去掉大括号

三、针对Azure MySQL的修复方案

如果确实是Azure MySQL,建议改用更简单的mysql-connector-python(无需ODBC):

1. 修改依赖与连接代码

  • 在requirements.txt中添加mysql-connector-python
  • 替换db.py的连接逻辑:
import mysql.connector
from mysql.connector import Error

server = 'xxx.mysql.database.azure.com'  # Azure MySQL的服务器地址格式
database = 'mydatabase'
username = 'xxxxxx'
password = 'xxxxxx'

def conn():
    try:
        connection = mysql.connector.connect(
            host=server,
            database=database,
            user=username,
            password=password,
            ssl_disabled=False  # Azure MySQL要求SSL
        )
        return connection
    except Error as e:
        print(f"数据库连接错误: {e}")
        raise

2. 修改API接口的查询逻辑

同样使用参数化查询避免SQL注入:

@app.get('/id/{id}')
async def op(id:int):
    conn = conn()
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM inventory WHERE id = %s", (id,))
    result = cursor.fetchone()
    cursor.close()
    conn.close()
    if not result:
        return {"error": "未找到对应记录"}
    return {"id": result[0], "name": result[1], "q": result[2]}

四、关键安全修复:避免SQL注入

你当前使用f"select * from dbo.inventory where id = {id}"拼接SQL语句,存在严重的SQL注入风险,必须改用参数化查询(上述示例已修正),这不仅是安全要求,也能避免特殊字符导致的SQL语法错误。


五、Azure App Service部署额外检查

  1. 确认App Service的启动命令与Dockerfile的CMD一致,比如使用uvicorn main:app --host 0.0.0.0 --port 80
  2. 在App Service的“日志流”中查看详细错误日志,确认驱动问题是否已解决
  3. 确认数据库防火墙允许App Service的出站IP访问(虽然你说无限制,但可再次验证)

内容的提问来源于stack exchange,提问作者Alex Raj Kaliamoorthy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 01:15:59