diff --git a/.github/workflows/ibis-ci.yml b/.github/workflows/ibis-ci.yml index 7267887c2..2cb3cb026 100644 --- a/.github/workflows/ibis-ci.yml +++ b/.github/workflows/ibis-ci.yml @@ -54,16 +54,13 @@ jobs: ~/.cargo/git/db/ wren-core-py/target/ key: ${{ runner.os }}-cargo-${{ hashFiles('wren-core-py/Cargo.lock') }} - - name: Install FreeTDS to be a ODBC driver + - name: Install MS ODBC SQL driver run: | - sudo apt-get update -y && sudo apt-get install -y unixodbc-dev freetds-dev tdsodbc - cat << EOF > free.tds.ini - [FreeTDS] - Description = FreeTDS driver - Driver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so - Setup = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so - EOF - sudo odbcinst -i -d -f free.tds.ini + sudo apt-get update + curl https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc + curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list + sudo apt-get update + sudo ACCEPT_EULA=Y apt-get -y install unixodbc-dev msodbcsql18 - name: Install dependencies run: | just install diff --git a/ibis-server/Dockerfile b/ibis-server/Dockerfile index 405d4a716..757d3240a 100644 --- a/ibis-server/Dockerfile +++ b/ibis-server/Dockerfile @@ -35,33 +35,19 @@ RUN just install-core $RUST_PROFILE FROM python:3.11-slim-buster AS runtime -# libpq-dev is required for psycopg2 -# unixodbc-dev, freetds-dev and tdsodbc are required for pyodbc -RUN apt-get update \ - && apt-get -y install libpq-dev \ - && apt-get -y install unixodbc-dev freetds-dev tdsodbc \ - && rm -rf /var/lib/apt/lists/* +# Add microsoft package list +RUN apt-get update \ + && apt-get install -y curl gnupg \ + && curl https://packages.microsoft.com/keys/microsoft.asc | tee /etc/apt/trusted.gpg.d/microsoft.asc \ + && curl https://packages.microsoft.com/config/debian/11/prod.list | tee /etc/apt/sources.list.d/mssql-release.list \ + && apt-get update -ARG TARGETPLATFORM +# Install msodbcsql 18 driver for mssql +RUN ACCEPT_EULA=Y apt-get -y install unixodbc-dev msodbcsql18 -# Install FreeTDS driver -RUN < free.tds.ini -[FreeTDS] -Description = FreeTDS driver -Driver = ${FREE_TDS_PATH} -Setup = ${FREE_TDS_PATH} -EOF -odbcinst -i -d -f free.tds.ini -EOT +# libpq-dev is required for psycopg2 +RUN apt-get -y install libpq-dev \ + && rm -rf /var/lib/apt/lists/* ENV VIRTUAL_ENV=/app/.venv \ PATH="/app/.venv/bin:$PATH" \ diff --git a/ibis-server/app/model/__init__.py b/ibis-server/app/model/__init__.py index 1f34005ac..0bd588d2a 100644 --- a/ibis-server/app/model/__init__.py +++ b/ibis-server/app/model/__init__.py @@ -82,10 +82,7 @@ class MSSqlConnectionInfo(BaseModel): database: SecretStr user: SecretStr password: SecretStr - driver: str = Field( - default="FreeTDS", - description="On Mac and Linux this is usually `FreeTDS. On Windows, it is usually `ODBC Driver 18 for SQL Server`", - ) + driver: str = Field(default="ODBC Driver 18 for SQL Server") tds_version: str = Field(default="8.0", alias="TDS_Version") kwargs: dict[str, str] | None = Field( description="Additional keyword arguments to pass to PyODBC", default=None diff --git a/ibis-server/docs/development.md b/ibis-server/docs/development.md index d45f547eb..18b150bc3 100644 --- a/ibis-server/docs/development.md +++ b/ibis-server/docs/development.md @@ -59,15 +59,21 @@ Please see [How to Add a New Data Source](how-to-add-data-source.md) for more in ## Troubleshooting -### MS SQL Server Tests -If you're having trouble running tests related to MS SQL Server, you may need to install the appropriate driver. For Linux or macOS, we recommend installing the `unixodbc` and `freetds` packages. -After installation, run `odbcinst -j` to check the path of the `odbcinst.ini` file. Then, find the path of `libtdsodbc.so` in freetds and add the following content to the odbcinst.ini file: -```ini -[FreeTDS] -Description = FreeTDS driver -Driver = /opt/homebrew/Cellar/freetds/1.4.17/lib/libtdsodbc.so -Setup = /opt/homebrew/Cellar/freetds/1.4.17/lib/libtdsodbc.so -FileUsage = 1 +### No driver for MS SQL Server +If you want to run tests related to MS SQL Server, you may need to install the `Microsoft ODBC 18 driver`. \ +You can follow the instructions to install the driver: +- [Microsoft ODBC driver for SQL Server (Linux)](https://learn.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server). +- [Microsoft ODBC driver for SQL Server (macOS)](https://learn.microsoft.com/en-us/sql/connect/odbc/linux-mac/install-microsoft-odbc-driver-sql-server-macos). +- [Microsoft ODBC driver for SQL Server (Windows)](https://learn.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server). + +### [ODBC Driver 18 for SQL Server]SSL Provider: [error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed:self signed certificate] +If you encounter this error, you can add the `TrustServerCertificate` parameter to the connection string. +```json +{ + "connectionInfo": { + "kwargs": { + "TrustServerCertificate": "YES" + } + } +} ``` -Adjust the paths as necessary for your system. - diff --git a/ibis-server/tests/routers/v2/connector/test_mssql.py b/ibis-server/tests/routers/v2/connector/test_mssql.py index 91f2e892b..1e3061981 100644 --- a/ibis-server/tests/routers/v2/connector/test_mssql.py +++ b/ibis-server/tests/routers/v2/connector/test_mssql.py @@ -79,7 +79,9 @@ def mssql(request) -> SqlServerContainer: mssql = SqlServerContainer( "mcr.microsoft.com/mssql/server:2019-CU27-ubuntu-20.04", dialect="mssql+pyodbc" ).start() - engine = sqlalchemy.create_engine(f"{mssql.get_connection_url()}?driver=FreeTDS") + engine = sqlalchemy.create_engine( + f"{mssql.get_connection_url()}?driver=ODBC+Driver+18+for+SQL+Server&TrustServerCertificate=YES" + ) pd.read_parquet(file_path("resource/tpch/data/orders.parquet")).to_sql( "orders", engine, index=False ) @@ -382,8 +384,9 @@ def _to_connection_info(mssql: SqlServerContainer): "user": mssql.username, "password": mssql.password, "database": mssql.dbname, + "kwargs": {"TrustServerCertificate": "YES"}, } def _to_connection_url(mssql: SqlServerContainer): info = _to_connection_info(mssql) - return f"mssql://{info['user']}:{info['password']}@{info['host']}:{info['port']}/{info['database']}?driver=FreeTDS" + return f"mssql://{info['user']}:{info['password']}@{info['host']}:{info['port']}/{info['database']}?driver=ODBC+Driver+18+for+SQL+Server&TrustServerCertificate=YES"