0

出于某种原因,我无法在python:3.7-slim-buster(debian)docker 映像中使用 FreeTDS 建立与 MSSQL Server 的连接。

代码

也可以在github上找到..

Dockerfile

FROM python:3.7-slim-buster

# install free-tds used for MSSQL connections
RUN sed -i "s#deb http://security.debian.org/debian-securitystretch/updates main#deb http://deb.debian.org/debian-security stretch/updates main#g" /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y g++
RUN apt-get install -y unixodbc-dev
RUN apt-get install -y freetds-dev
RUN apt-get install -y freetds-bin
RUN apt-get install -y tdsodbc

# create a freetds odbc driver path
# required so python scripts can reference {FreeTDS} in their pypyodbc connections
RUN echo "[FreeTDS]" >> /etc/odbcinst.ini
RUN echo "Description=FreeTDS Driver" >> /etc/odbcinst.ini
RUN echo "Driver=/usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so" >> /etc/odbcinst.ini
RUN echo "Setup=/usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so" >> /etc/odbcinst.ini

RUN apt-get clean

COPY requirements.txt .
RUN pip install --default-timeout=2000 --no-cache-dir -r requirements.txt

COPY example.py .

# set entrypoint
ENTRYPOINT python example.py

example.py

#!/usr/bin/python3
import platform

import pandas as pd
import pypyodbc


def connect():
    driver = '{FreeTDS}' if platform.system() != 'Windows' else '{ODBC Driver 17 for SQL Server}'
    creds = {  # dummy credentials
        'server': 'mssqlserver.mydomain.com',
        'port': '1443',
        'database': 'my_database_name',
        'username': 'my_username',
        'password': 'my_password'
    }
    return pypyodbc.connect(
        (
            'DRIVER={driver};'
            'SERVER={server};'
            'PORT={port};'
            'DATABASE={database};'
            'UID={username};'
            'PWD={password};'
            'TDS_Version={tds_version};'
        ).format(
            driver=driver,
            server=creds['server'],
            port=creds['port'],
            database=creds['database'],
            username=creds['username'],
            password=creds['password'],
            tds_version='7.2'
        )
    )


def dummy_query(conn):
    sql_query = '''SELECT * FROM (VALUES ('Hello world'),('Hello world')) t1 (col1) WHERE 1=1'''
    return pd.read_sql(sql_query, conn)


if __name__ == '__main__':
    conn = connect()
    data = dummy_query(conn)
    print(data)

requirements.txt

pandas==0.25.1
pypyodbc>=1.3.4

在 Windows 上运行时

工作正常

python example.py

          col1
0  Hello world
1  Hello world

使用 docker 时

不起作用,失败并带有pypyodbc.DatabaseError..

构建 docker 镜像

docker build . -t freetds_issue

运行 docker 镜像

docker run freetds_issue

Traceback (most recent call last):
  File "example.py", line 51, in <module>
    conn = connect()
  File "example.py", line 40, in connect
    tds_version='7.2'
  File "/usr/local/lib/python3.7/site-packages/pypyodbc.py", line 2454, in __init__
    self.connect(connectString, autocommit, ansi, timeout, unicode_results, readonly)
  File "/usr/local/lib/python3.7/site-packages/pypyodbc.py", line 2507, in connect
    check_success(self, ret)
  File "/usr/local/lib/python3.7/site-packages/pypyodbc.py", line 1009, in check_success
    ctrl_err(SQL_HANDLE_DBC, ODBC_obj.dbc_h, ret, ODBC_obj.ansi)
  File "/usr/local/lib/python3.7/site-packages/pypyodbc.py", line 987, in ctrl_err
    raise DatabaseError(state,err_text)
pypyodbc.DatabaseError: ('08S01', '[08S01] [FreeTDS][SQL Server]Unable to connect: Adaptive Server is unavailable or does not exist')

docker内部的一些输出

docker run -it --entrypoint "/bin/bash" freetds_issue

输出tsql -C

Compile-time settings (established with the "configure" script)
                            Version: freetds v1.00.104
             freetds.conf directory: /etc/freetds
     MS db-lib source compatibility: no
        Sybase binary compatibility: yes
                      Thread safety: yes
                      iconv library: yes
                        TDS version: 4.2
                              iODBC: no
                           unixodbc: yes
              SSPI "trusted" logins: no
                           Kerberos: yes
                            OpenSSL: no
                             GnuTLS: yes
                               MARS: no

输出tsql -LH {server_ip}

     ServerName SERVERNAME
   InstanceName MSSQLSERVER
    IsClustered No
        Version 14.0.1000.169
            tcp 1433

奇怪的是,使用tsqlCLI 连接似乎可以工作..

tsql -S mssqlserver.mydomain.com -U my_username

Password:
locale is "C.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
1> exit
4

0 回答 0