简体   繁体   中英

Cannot connect to Azure SQL using an alpine docker image with Python

I have an alpine based docker image, with support for Python, through which I am trying to connect to Azure SQL service. Here is my simple connection code.

import pyodbc
server = 'blah1.database.windows.net'
database = 'mydb1'
username = 'myadmin'
password = 'XXXXXX'
driver= 'ODBC Driver 17 for SQL Server'
conn = pyodbc.connect('DRIVER='+driver+';SERVER='+server+';PORT=1433;DATABASE='+database+';UID='+username+';PWD='+ password)
c = conn.cursor()
c.execute("SELECT * FROM dbo.customers")

print(c.fetchall())
print(type(c.fetchall()))

conn.commit()
conn.close()

When connecting to SQL server in Azure, the code generates the following error:

pyodbc.Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib 'ODBC Driver 17 for SQL Server' : file not found (0) (SQLDriverConnect)")nect)")

Here is my Dockerfile:

FROM tiangolo/uwsgi-nginx:python3.7-alpine3.8

RUN apk update
RUN apk add gcc libc-dev g++ libffi-dev libxml2 unixodbc-dev

LABEL Name=code9 Version=0.0.1
EXPOSE 8000
ENV LISTEN_PORT=8000

ENV UWSGI_INI uwsgi.ini

WORKDIR /app
ADD . /app

RUN chmod g+w /app
RUN chmod g+w /app/db.sqlite3


RUN python3 -m pip install -r requirements.txt

I am assuming that I am unixODBC will take care of the connection with SQL server in Azure or do I need to install MS SQL driver for alpine? Is there one available? I couldn't find one. Please help.

To confirm setup:

apk update && apk add build-base unixodbc-dev freetds-dev
pip install pyodbc

Why install both unixodbc and freetds? Pyodbc's pip install requires the packages in unixodbc-dev and the gcc libraries in build-base, so no getting around that. The freetds driver tends to have fewer issues with pyodbc, and is leaned on heavily by pymssql , which I've been using in docker in lieu of pyodbc. That's a personal preference, though, you could just include the unixodbc driver. Now, to find the driver

import pyodbc
pyodbc.drivers()
# []

Pyodbc can't locate them, but they are definitely installed, so we can find them with a shell script:

find / -name *odbc.so
/usr/lib/libtdsodbc.so
/usr/lib/libodbc.so

Now, we can automate this with the subprocess library to set the driver location manually:

import subprocess

s = subprocess.Popen('find / -name *odbc.so -type f', stdout=subprocess.PIPE, shell=True).communicate()

f, _ = s

# You can change this particular loop to select whatever driver you prefer
driver = [driver for driver in f.decode().split() if 'tds' in driver][0]

driver
# '/usr/lib/libtdsodbc.so'

username = 'someuser'
server = 'someserver'
database = 'somedatabase'

conn = pyodbc.connect('DRIVER='+driver+';SERVER='+server+';PORT=1433;DATABASE='+database+';UID='+username+';PWD='+ password)

Alternatively, you can add the configuration to /etc/odbcinst.ini as mentioned here :

[FreeTDS]
Description=FreeTDS Driver 
Driver=/usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so

Then

import pyodbc

pyodbc.drivers()
['FreeTDS']
RUN wget https://download.microsoft.com/download/e/4/e/e4e67866-dffd-428c-aac7-8d28ddafb39b/msodbcsql17_17.7.2.1-1_amd64.apk  && \
    wget https://download.microsoft.com/download/e/4/e/e4e67866-dffd-428c-aac7-8d28ddafb39b/mssql-tools_17.7.1.1-1_amd64.apk  && \
    apk add --allow-untrusted msodbcsql17_17.7.2.1-1_amd64.apk && \
    apk add --allow-untrusted mssql-tools_17.7.1.1-1_amd64.apk

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM