Skip to content

Commit

Permalink
fix(mssql): escape special characters for odbc (#889)
Browse files Browse the repository at this point in the history
  • Loading branch information
grieve54706 authored Nov 5, 2024
1 parent 60a595d commit d624ea6
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 5 deletions.
12 changes: 9 additions & 3 deletions ibis-server/app/model/data_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,16 @@ def get_clickhouse_connection(info: ClickHouseConnectionInfo) -> BaseBackend:
password=info.password.get_secret_value(),
)

@staticmethod
def get_mssql_connection(info: MSSqlConnectionInfo) -> BaseBackend:
@classmethod
def get_mssql_connection(cls, info: MSSqlConnectionInfo) -> BaseBackend:
return ibis.mssql.connect(
host=info.host.get_secret_value(),
port=info.port.get_secret_value(),
database=info.database.get_secret_value(),
user=info.user.get_secret_value(),
password=info.password.get_secret_value(),
password=cls._escape_special_characters_for_odbc(
info.password.get_secret_value()
),
driver=info.driver,
TDS_Version=info.tds_version,
**info.kwargs if info.kwargs else dict(),
Expand Down Expand Up @@ -161,3 +163,7 @@ def get_trino_connection(info: TrinoConnectionInfo) -> BaseBackend:
user=(info.user and info.user.get_secret_value()),
password=(info.password and info.password.get_secret_value()),
)

@staticmethod
def _escape_special_characters_for_odbc(value: str) -> str:
return "{" + value.replace("}", "}}") + "}"
8 changes: 6 additions & 2 deletions ibis-server/tests/routers/v2/connector/test_mssql.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import base64
import urllib

import orjson
import pandas as pd
Expand Down Expand Up @@ -77,7 +78,9 @@ def manifest_str():
@pytest.fixture(scope="module")
def mssql(request) -> SqlServerContainer:
mssql = SqlServerContainer(
"mcr.microsoft.com/mssql/server:2019-CU27-ubuntu-20.04", dialect="mssql+pyodbc"
"mcr.microsoft.com/mssql/server:2019-CU27-ubuntu-20.04",
dialect="mssql+pyodbc",
password="{R;3G1/8Al2AniRye",
).start()
engine = sqlalchemy.create_engine(
f"{mssql.get_connection_url()}?driver=ODBC+Driver+18+for+SQL+Server&TrustServerCertificate=YES"
Expand Down Expand Up @@ -150,6 +153,7 @@ def test_query(manifest_str, mssql: SqlServerContainer):
"bytea_column": "object",
}

@pytest.mark.skip("Wait ibis handle special characters in connection string")
def test_query_with_connection_url(manifest_str, mssql: SqlServerContainer):
connection_url = _to_connection_url(mssql)
response = client.post(
Expand Down Expand Up @@ -389,4 +393,4 @@ def _to_connection_info(mssql: SqlServerContainer):

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=ODBC+Driver+18+for+SQL+Server&TrustServerCertificate=YES"
return f"mssql://{info['user']}:{urllib.parse.quote_plus(info['password'])}@{info['host']}:{info['port']}/{info['database']}?driver=ODBC+Driver+18+for+SQL+Server&TrustServerCertificate=YES"

0 comments on commit d624ea6

Please sign in to comment.