Skip to content

Commit

Permalink
refactor(sqlalchemy): clean up quoting implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
cpcloud authored and kszucs committed Jan 21, 2023
1 parent 9e80231 commit 506ce01
Show file tree
Hide file tree
Showing 7 changed files with 13 additions and 14 deletions.
6 changes: 5 additions & 1 deletion ibis/backends/base/sql/alchemy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,10 @@ def insert(
f"The given obj is of type {type(obj).__name__} ."
)

def _quote(self, name: str) -> str:
"""Quote an identifier."""
return self.con.dialect.identifier_preparer.quote(name)

def _get_temp_view_definition(
self,
name: str,
Expand Down Expand Up @@ -613,7 +617,7 @@ def _create_temp_view(self, view: sa.Table, definition: sa.sql.Selectable) -> No
raw_name = view.name
if raw_name not in self._temp_views and raw_name in self.list_tables():
raise ValueError(f"{raw_name} already exists as a table or view")
name = self.con.dialect.identifier_preparer.quote_identifier(view.name)
name = self._quote(raw_name)
lines, params = self._get_compiled_statement(definition, name)
with self.begin() as con:
for line in lines:
Expand Down
10 changes: 3 additions & 7 deletions ibis/backends/duckdb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ def normalize_filenames(source_list):
return list(map(util.normalize_filename, source_list))


def _quote(name: str):
return _dialect.identifier_preparer.quote(name)


def _format_kwargs(kwargs):
return (
f"{k}='{v}'" if isinstance(v, str) else f"{k}={v!r}" for k, v in kwargs.items()
Expand Down Expand Up @@ -237,7 +233,7 @@ def read_csv(
if not table_name:
table_name = f"ibis_read_csv_{next(csv_n)}"

quoted_table_name = _quote(table_name)
quoted_table_name = self._quote(table_name)

# auto_detect and columns collide, so we set auto_detect=True
# unless COLUMNS has been specified
Expand Down Expand Up @@ -309,7 +305,7 @@ def read_parquet(
dataset = str(source_list)
table_name = table_name or f"ibis_read_parquet_{next(pa_n)}"

quoted_table_name = _quote(table_name)
quoted_table_name = self._quote(table_name)
sql = f"""CREATE OR REPLACE VIEW {quoted_table_name} AS
SELECT * FROM read_parquet({dataset})"""

Expand Down Expand Up @@ -362,7 +358,7 @@ def read_postgres(self, uri, table_name=None):
"`table_name` is required when registering a postgres table"
)
self._load_extensions(["postgres_scanner"])
quoted_table_name = _quote(table_name)
quoted_table_name = self._quote(table_name)
sql = (
f"CREATE OR REPLACE VIEW {quoted_table_name} AS "
f"SELECT * FROM postgres_scan_pushdown('{uri}', 'public', '{table_name}')"
Expand Down
2 changes: 1 addition & 1 deletion ibis/backends/mssql/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
)
def test_get_schema_from_query(con, server_type, expected_type):
raw_name = f"tmp_{ibis.util.guid()}"
name = con.con.dialect.identifier_preparer.quote_identifier(raw_name)
name = con._quote(raw_name)
expected_schema = ibis.schema(dict(x=expected_type))
try:
with con.begin() as c:
Expand Down
2 changes: 1 addition & 1 deletion ibis/backends/mysql/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
)
def test_get_schema_from_query(con, mysql_type, expected_type):
raw_name = ibis.util.guid()
name = con.con.dialect.identifier_preparer.quote_identifier(raw_name)
name = con._quote(raw_name)
# temporary tables get cleaned up by the db when the session ends, so we
# don't need to explicitly drop the table
with con.begin() as c:
Expand Down
2 changes: 1 addition & 1 deletion ibis/backends/postgres/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def udf(

def _metadata(self, query: str) -> Iterable[tuple[str, dt.DataType]]:
raw_name = util.guid()
name = self.con.dialect.identifier_preparer.quote_identifier(raw_name)
name = self._quote(raw_name)
type_info_sql = f"""\
SELECT
attname,
Expand Down
2 changes: 1 addition & 1 deletion ibis/backends/postgres/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ def test_create_and_drop_table(con, temp_table, params):
)
def test_get_schema_from_query(con, pg_type, expected_type):
raw_name = ibis.util.guid()
name = con.con.dialect.identifier_preparer.quote_identifier(raw_name)
name = con._quote(raw_name)
with con.begin() as c:
c.execute(
sa.text(f"CREATE TEMPORARY TABLE {name} (x {pg_type}, y {pg_type}[])")
Expand Down
3 changes: 1 addition & 2 deletions ibis/backends/sqlite/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,7 @@ def attach(self, name: str, path: str | Path) -> None:
>>> con1.attach("new", "new.db")
>>> con1.list_tables(database="new")
"""
quoted_name = self.con.dialect.identifier_preparer.quote(name)
self.raw_sql(f"ATTACH DATABASE {str(path)!r} AS {quoted_name}")
self.raw_sql(f"ATTACH DATABASE {str(path)!r} AS {self._quote(name)}")

def _get_sqla_table(
self, name: str, schema: str | None = None, autoload: bool = True, **_: Any
Expand Down

0 comments on commit 506ce01

Please sign in to comment.