Python - 调试模块加载问题

0 投票
1 回答
30 浏览
提问于 2025-04-14 15:41

我正在尝试在AWS上部署一个Python的Lambda函数,并且需要用到pyodbc这个库来连接数据库。当我运行这个函数并试图连接数据库时,出现了一个错误,提示“connect”这个属性不存在。

我通过Terraform来部署我的函数。

我可以成功导入“pyodbc”,这说明Lambda找到了这个模块。层的文件夹结构如下...

/lib
/msodbcsql18
/python
    /python/pyodbc-5-1.0.dist-info
    /python/pyodbc.cpython-38-x86_64-linux-gnu.so
    /python/pyodbc.pyi
/odbc.ini
/odbcinst.ini

这是我的函数代码...

import pyodbc
import os
import platform

def lambda_handler(event, context):

    context.log(f"Platform: {platform.platform()}\n")

    for item in os.listdir("/opt"):
        context.log(f"ODBC Files: {item}\n")

    conn_str = 'DRIVER={0};SERVER={1};UID={2};PWD={3};Port={4};TrustServerCertificate=yes'.format(
        "{ODBC Driver 18 for SQL Server}",
        os.environ["server_name"],
        os.environ["user_name"],
        os.environ["password"],
        os.environ["ip_port"]
    )

    try:
        context.log("[INFO] Attempting database connection\n")
        db = pyodbc.connect(conn_str)
    except Exception as e:
        context.log(f"[ERROR] Connection failed - {e}\n")
        return

我认为错误提示说pyodbc的“connect”属性不存在,说明ODBC驱动程序并不重要。换句话说,如果pyodbc模块没有正确加载,就无法尝试加载ODBC驱动。

我的Lambda平台是“Linux-5.10.209-218.812.amzn2.x86_64-x86_64-with-glibc2.2.5”。我觉得这和pyodbc的二进制文件“pyodbc.cpython-38-x86_64-linux-gnu.so”是匹配的,所以我比较确定没有平台或架构兼容性的问题。不过,我不知道怎么判断pyodbc的二进制文件是否真的加载了,或者在加载时是否出现了错误。

我花了几天时间在GitHub和其他博客上尝试不同的pyodbc层,但运气不太好。

那么,我到底哪里做错了呢?我认为此时ODBC驱动程序不重要的假设是正确的吗?

1 个回答

0

我在使用这个Dockerfile https://github.com/davidcomerford/pyodbc-mssql-lambda-layer/blob/main/Dockerfile.python.3.11.x86_64 来构建一个用于创建ODBC层的镜像。

里面有一行代码是用来编译unixODBC的,但出现了一个错误,提示它无法猜测目标平台。所以我把它设置为编译x86_64架构。我发现虽然我的Dockerfile是配置为编译x86_64,但实际上却在编译arm64架构。我修改了Dockerfile,让它编译arm64,结果一切开始正常工作了。

我一直是Windows用户,最近才开始使用M2的MAC。我怀疑在MAC上使用Docker时,尝试编译x86_64架构可能会有问题,尽管它可以运行x86的容器。

撰写回答