I'm trying to deploy an AWS Python Lambda function with a pyodbc layer for database access. When I run the function and attempt to connect to a database I get an error indicating the "connect" attribute doesn't exist.
I'm deploying my function via Terraform.
The "import pyodbc" completes ok which tells me Lambda found the module. The layer folder structure is as follows...
/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
Here is the function code...
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
I assume that because the error says the pyodbc "connect" attribute doesn't exist that the ODBC driver is irrelevant. In other words, if the pyodbc module doesn't load correctly it can't try to load the ODBC driver.
The lambda platform is "Linux-5.10.209-218.812.amzn2.x86_64-x86_64-with-glibc2.2.5". I think this matches the pyodbc binary "pyodbc.cpython-38-x86_64-linux-gnu.so", so I'm fairly sure there aren't any platform or architectural compatibility issues. However, I don't know how to determine if the pyodbc binary actually loaded, or if there were errors when loading it.
I've spent a couple days fiddling with various pyodbc layers on GitHub and other blogs, but haven't had much luck.
Soooo, what am I doing wrong? Is my assumption the ODBC driver is irrelevant at this point correct?
I was using this Dockerfile https://github.com/davidcomerford/pyodbc-mssql-lambda-layer/blob/main/Dockerfile.python.3.11.x86_64 to build an image for creating an ODBC layer.
There is a line that compiles unixODBC that was returning an error indicating it couldn't guess the target platform. So I set it to compile for x86_64. I discovered that although my Dockerfile was configured to compile for x86_64 it was compiling for arm64. I altered the Dockerfile to compile for arm64 and things started working as expected.
I've been a Windows user all my career and recently jumped into the deep end of MAC on M2. I suspect Docker on MAC didn't like the attempt to compile for x86_64 even though it will run x86 containers.