|
8 | 8 | from contextlib import closing
|
9 | 9 | from operator import itemgetter
|
10 | 10 | from typing import TYPE_CHECKING, Any
|
| 11 | +from urllib.parse import unquote_plus |
11 | 12 |
|
12 | 13 | import pyodbc
|
13 | 14 | import sqlglot as sg
|
|
21 | 22 | import ibis.expr.schema as sch
|
22 | 23 | import ibis.expr.types as ir
|
23 | 24 | from ibis import util
|
24 |
| -from ibis.backends import CanCreateCatalog, CanCreateDatabase, CanCreateSchema, NoUrl |
| 25 | +from ibis.backends import CanCreateCatalog, CanCreateDatabase, CanCreateSchema |
25 | 26 | from ibis.backends.sql import SQLBackend
|
26 | 27 | from ibis.backends.sql.compilers.base import STAR, C
|
27 | 28 |
|
28 | 29 | if TYPE_CHECKING:
|
29 | 30 | from collections.abc import Iterable, Mapping
|
| 31 | + from urllib.parse import ParseResult |
30 | 32 |
|
31 | 33 | import pandas as pd
|
32 | 34 | import polars as pl
|
@@ -73,7 +75,7 @@ def datetimeoffset_to_datetime(value):
|
73 | 75 | # Databases: sys.schemas
|
74 | 76 |
|
75 | 77 |
|
76 |
| -class Backend(SQLBackend, CanCreateCatalog, CanCreateDatabase, CanCreateSchema, NoUrl): |
| 78 | +class Backend(SQLBackend, CanCreateCatalog, CanCreateDatabase, CanCreateSchema): |
77 | 79 | name = "mssql"
|
78 | 80 | compiler = sc.mssql.compiler
|
79 | 81 | supports_create_or_replace = False
|
@@ -169,6 +171,40 @@ def _post_connect(self):
|
169 | 171 | with closing(self.con.cursor()) as cur:
|
170 | 172 | cur.execute("SET DATEFIRST 1")
|
171 | 173 |
|
| 174 | + def _from_url(self, url: ParseResult, **kwargs): |
| 175 | + database, *_ = url.path[1:].split("/", 1) |
| 176 | + kwargs.update( |
| 177 | + { |
| 178 | + "user": url.username, |
| 179 | + "password": unquote_plus(url.password or ""), |
| 180 | + "host": url.hostname, |
| 181 | + "database": database or "", |
| 182 | + "port": url.port or None, |
| 183 | + } |
| 184 | + ) |
| 185 | + |
| 186 | + self._convert_kwargs(kwargs) |
| 187 | + |
| 188 | + if "host" in kwargs and not kwargs["host"]: |
| 189 | + del kwargs["host"] |
| 190 | + |
| 191 | + if "user" in kwargs and not kwargs["user"]: |
| 192 | + del kwargs["user"] |
| 193 | + |
| 194 | + if "password" in kwargs and kwargs["password"] is None: |
| 195 | + del kwargs["password"] |
| 196 | + |
| 197 | + if "port" in kwargs and kwargs["port"] is None: |
| 198 | + del kwargs["port"] |
| 199 | + |
| 200 | + if "database" in kwargs and not kwargs["database"]: |
| 201 | + del kwargs["database"] |
| 202 | + |
| 203 | + if "driver" in kwargs and not kwargs["driver"]: |
| 204 | + del kwargs["driver"] |
| 205 | + |
| 206 | + return self.connect(**kwargs) |
| 207 | + |
172 | 208 | def get_schema(
|
173 | 209 | self, name: str, *, catalog: str | None = None, database: str | None = None
|
174 | 210 | ) -> sch.Schema:
|
|
0 commit comments