AWS Lambda中Django连接SQL Server 2019时ODBC驱动缺失问题求助
问题:AWS Lambda环境中Django连接SQL Server 2019失败
在AWS Lambda的Amazon Linux环境中,部署基于Django3.2.14的项目(使用mssql-django1.1.3库),尝试连接另一服务器上的SQL Server 2019时,无法建立数据库连接,核心报错:
('01000', "[01000] [unixODBC][Driver Manager]Can't open lib 'ODBC Driver 17 for SQL Server' : file not found (0) (SQLDriverConnect)")
部署操作步骤
- 启动Docker镜像命令:
docker run -t -i -p 8000:8000 -e AWS_PROFILE=zappa -v "/task" -v C:\Users\Ishan/.aws/:/root/.aws --rm zappa-docker-image
- Dockerfile内容:
from lambci/lambda:build-python3.7 #make this default working directory WORKDIR /task #expose tcp port 8000 for debugging EXPOSE 8000 #Prompt to remind you are in zappashell RUN echo 'export PS1="\[\e[36m\]zappashell>\[\e[m\] "' >> /root/.bashrc CMD ["bash"]
- 环境启动后,安装msodbcdriver17的命令:
RUN curl http://mirror.centos.org/centos/7/os/x86_64/Packages/unixODBC-2.3.1-14.el7.x86_64.rpm > /tmp/unixODBC-2.3.1-14.el7.x86_64.rpm RUN yum -y install /tmp/unixODBC-2.3.1-14.el7.x86_64.rpm RUN curl http://mirror.centos.org/centos/7/os/x86_64/Packages/unixODBC-devel-2.3.1-14.el7.x86_64.rpm > /tmp/unixODBC-devel-2.3.1-14.el7.x86_64.rpm RUN yum -y install /tmp/unixODBC-devel-2.3.1-14.el7.x86_64.rpm RUN curl https://packages.microsoft.com/config/rhel/7/prod.repo > /etc/yum.repos.d/mssql-release.repo RUN ACCEPT_EULA=Y yum -y install msodbcsql17
msodbcsql17安装路径为/opt/microsoft/
odbcinst -j执行结果:
unixODBC 2.3.1 DRIVERS............: /etc/odbcinst.ini SYSTEM DATA SOURCES: /etc/odbc.ini FILE DATA SOURCES..: /etc/ODBCDataSources USER DATA SOURCES..: /root/.odbc.ini SQLULEN Size.......: 8 SQLLEN Size........: 8 SQLSETPOSIROW Size.: 8
odbcinst.ini内容:
[PostgreSQL] Description=ODBC for PostgreSQL Driver=/usr/lib/psqlodbcw.so Setup=/usr/lib/libodbcpsqlS.so Driver64=/usr/lib64/psqlodbcw.so Setup64=/usr/lib64/libodbcpsqlS.so FileUsage=1 [MySQL] Description=ODBC for MySQL Driver=/usr/lib/libmyodbc5.so Setup=/usr/lib/libodbcmyS.so Driver64=/usr/lib64/libmyodbc5.so Setup64=/usr/lib64/libodbcmyS.so FileUsage=1 [ODBC Driver 17 for SQL Server] Description=Microsoft ODBC Driver 17 for SQL Server Driver=/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.10.so.1.1 UsageCount=1
完整报错栈
[1662099546582] Internal Server Error: /dev/api/1.0/accounts/auth_token/ [1662099546582] Traceback (most recent call last): [1662099546582] File "/var/task/django/db/backends/base/base.py", line 219, in ensure_connection [1662099546582] self.connect() [1662099546582] File "/var/task/django/utils/asyncio.py", line 33, in inner [1662099546582] return func(*args, **kwargs) [1662099546582] File "/var/task/django/db/backends/base/base.py", line 200, in connect [1662099546582] self.connection = self.get_new_connection(conn_params) [1662099546582] File "/var/task/mssql/base.py", line 353, in get_new_connection [1662099546582] conn = Database.connect(connstr, **args) [1662099546582] pyodbc.Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib 'ODBC Driver 17 for SQL Server' : file not found (0) (SQLDriverConnect)") [1662099546582] The above exception was the direct cause of the following exception: [1662099546582] Traceback (most recent call last): [1662099546582] File "/var/task/django/core/handlers/exception.py", line 47, in inner [1662099546582] response = get_response(request) [1662099546582] File "/var/task/django/core/handlers/base.py", line 181, in _get_response [1662099546582] response = wrapped_callback(request, *callback_args, **callback_kwargs) [1662099546582] File "/var/task/django/views/decorators/csrf.py", line 54, in wrapped_view [1662099546582] return view_func(*args, **kwargs) [1662099546582] File "/var/task/django/views/generic/base.py", line 70, in view [1662099546582] return self.dispatch(request, *args, **kwargs) [1662099546582] File "/var/task/rest_framework/views.py", line 509, in dispatch [1662099546582] response = self.handle_exception(exc) [1662099546582] File "/var/task/rest_framework/views.py", line 469, in handle_exception [1662099546582] self.raise_uncaught_exception(exc) [1662099546582] File "/var/task/rest_framework/views.py", line 480, in raise_uncaught_exception [1662099546582] raise exc [1662099546582] File "/var/task/rest_framework/views.py", line 506, in dispatch [1662099546582] response = handler(request, *args, **kwargs) [1662099546582] File "/var/task/accounts/views.py", line 309, in post [1662099546582] user = User.objects.get(email=email) [1662099546582] File "/var/task/django/db/models/manager.py", line 85, in manager_method [1662099546582] return getattr(self.get_queryset(), name)(*args, **kwargs) [1662099546582] File "/var/task/django/db/models/query.py", line 431, in get [1662099546582] num = len(clone) [1662099546582] File "/var/task/django/db/models/query.py", line 262, in __len__ [1662099546582] self._fetch_all() [1662099546582] File "/var/task/django/db/models/query.py", line 1324, in _fetch_all [1662099546582] self._result_cache = list(self._iterable_class(self)) [1662099546582] File "/var/task/django/db/models/query.py", line 51, in __iter__ [1662099546582] results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size) [1662099546582] File "/var/task/django/db/models/sql/compiler.py", line 1162, in execute_sql [1662099546582] sql, params = self.as_sql() [1662099546582] File "/var/task/mssql/compiler.py", line 188, in as_sql [1662099546582] supports_offset_clause = self.connection.sql_server_version >= 2012 [1662099546582] File "/var/task/django/utils/functional.py", line 48, in __get__ [1662099546582] res = instance.__dict__[self.name] = self.func(instance) [1662099546582] File "/var/task/mssql/base.py", line 445, in sql_server_version [1662099546582] with self.temporary_connection() as cursor: [1662099546582] File "/var/lang/lib/python3.7/contextlib.py", line 112, in __enter__ [1662099546582] return next(self.gen) [1662099546582] File "/var/task/django/db/backends/base/base.py", line 603, in temporary_connection [1662099546582] with self.cursor() as cursor: [1662099546582] File "/var/task/django/utils/asyncio.py", line 33, in inner [1662099546582] return func(*args, **kwargs) [1662099546582] File "/var/task/django/db/backends/base/base.py", line 259, in cursor [1662099546582] return self._cursor() [1662099546582] File "/var/task/mssql/base.py", line 246, in _cursor [1662099546582] conn = super()._cursor() [1662099546582] File "/var/task/django/db/backends/base/base.py", line 235, in _cursor [1662099546582] self.ensure_connection() [1662099546582] File "/var/task/django/utils/asyncio.py", line 33, in inner [1662099546582] return func(*args, **kwargs) [1662099546582] File "/var/task/django/db/backends/base/base.py", line 219, in ensure_connection [1662099546582] self.connect() [1662099546582] File "/var/task/django/db/utils.py", line 90, in __exit__ [1662099546582] raise dj_exc_value.with_traceback(traceback) from exc_value [1662099546582] File "/var/task/django/db/backends/base/base.py", line 219, in ensure_connection [1662099546582] self.connect() [1662099546582] File "/var/task/django/utils/asyncio.py", line 33, in inner [1662099546582] return func(*args, **kwargs) [1662099546582] File "/var/task/django/db/backends/base/base.py", line 200, in connect [1662099546582] self.connection = self.get_new_connection(conn_params) [1662099546582] File "/var/task/mssql/base.py", line 353, in get_new_connection [1662099546582] conn = Database.connect(connstr, **args) [1662099546582] django.db.utils.Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib 'ODBC Driver 17 for SQL Server' : file not found (0) (SQLDriverConnect)")
系统信息
执行cat /etc/os-release结果:
NAME="Amazon Linux AMI" VERSION="2018.03" ID="amzn" ID_LIKE="rhel fedora" VERSION_ID="2018.03" PRETTY_NAME="Amazon Linux AMI 2018.03" ANSI_COLOR="0;33" CPE_NAME="cpe:/o:amazon:linux:2018.03:ga" HOME_URL="http://aws.amazon.com/amazon-linux-ami/" VARIANT_ID="202011181029-al2018.03.426.0"
根因分析
- 构建与运行环境不匹配:使用
lambci/lambda:build-python3.7构建环境,但Lambda实际运行的是Amazon Linux AMI 2018.03,构建时安装的ODBC驱动及依赖未被正确打包到部署包,导致运行时找不到驱动文件。 - 驱动路径加载失败:Lambda运行时的系统库路径未包含
/opt/microsoft/msodbcsql17/lib64,动态链接器无法定位驱动依赖的库文件。 - 依赖库缺失:msodbcsql17依赖的系统库(如
libssl、libcrypto)在Lambda环境中版本或路径不匹配,导致驱动无法正常加载。
解决办法
方案1:使用Lambda层打包ODBC驱动
- 在与Lambda运行环境一致的Amazon Linux AMI 2018.03容器/实例中安装驱动:
curl http://mirror.centos.org/centos/7/os/x86_64/Packages/unixODBC-2.3.1-14.el7.x86_64.rpm > /tmp/unixODBC-2.3.1-14.el7.x86_64.rpm yum -y install /tmp/unixODBC-2.3.1-14.el7.x86_64.rpm curl http://mirror.centos.org/centos/7/os/x86_64/Packages/unixODBC-devel-2.3.1-14.el7.x86_64.rpm > /tmp/unixODBC-devel-2.3.1-14.el7.x86_64.rpm yum -y install /tmp/unixODBC-devel-2.3.1-14.el7.x86_64.rpm curl https://packages.microsoft.com/config/rhel/7/prod.repo > /etc/yum.repos.d/mssql-release.repo ACCEPT_EULA=Y yum -y install msodbcsql17
- 复制驱动文件到层目录:
mkdir -p lambda-layer/opt/microsoft/msodbcsql17/lib64 cp
相关产品推荐
相关产品推荐

