From d36a068523b8927490c79d94de2538ec7ae5072f Mon Sep 17 00:00:00 2001 From: ncclementi Date: Tue, 17 Sep 2024 13:01:35 -0400 Subject: [PATCH] refactor(api): remove schema --- ibis/backends/bigquery/__init__.py | 51 ++++---------------- ibis/backends/datafusion/__init__.py | 10 ++-- ibis/backends/duckdb/__init__.py | 13 ++---- ibis/backends/mssql/__init__.py | 6 +-- ibis/backends/mysql/__init__.py | 19 +------- ibis/backends/oracle/__init__.py | 19 +------- ibis/backends/postgres/__init__.py | 20 +------- ibis/backends/snowflake/__init__.py | 10 +--- ibis/backends/sql/__init__.py | 69 +++++----------------------- ibis/backends/sqlite/__init__.py | 5 -- ibis/backends/trino/__init__.py | 5 +- 11 files changed, 38 insertions(+), 189 deletions(-) diff --git a/ibis/backends/bigquery/__init__.py b/ibis/backends/bigquery/__init__.py index df1b2f3674d98..308defd15db6a 100644 --- a/ibis/backends/bigquery/__init__.py +++ b/ibis/backends/bigquery/__init__.py @@ -582,9 +582,11 @@ def drop_database( self.raw_sql(stmt.sql(self.name)) def table( - self, name: str, database: str | None = None, schema: str | None = None + self, + name: str, + database: str | None = None, ) -> ir.Table: - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) table = sg.parse_one(f"`{name}`", into=sge.Table, read=self.name) # Bigquery, unlike other backends, had existing support for specifying @@ -722,7 +724,6 @@ def insert( self, table_name: str, obj: pd.DataFrame | ir.Table | list | dict, - schema: str | None = None, database: str | None = None, overwrite: bool = False, ): @@ -734,15 +735,13 @@ def insert( The name of the table to which data needs will be inserted obj The source data or expression to insert - schema - The name of the schema that the table is located in database Name of the attached database that the table is located in. overwrite If `True` then replace existing contents of table """ - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) catalog, db = self._to_catalog_db_tuple(table_loc) if catalog is None: catalog = self.current_catalog @@ -896,7 +895,6 @@ def list_tables( self, like: str | None = None, database: tuple[str, str] | str | None = None, - schema: str | None = None, ) -> list[str]: """List the tables in the database. @@ -924,10 +922,8 @@ def list_tables( To specify a table in a separate BigQuery dataset, you can pass in the dataset and project as a string `"dataset.project"`, or as a tuple of strings `(dataset, project)`. - schema - [deprecated] The schema (dataset) inside `database` to perform the list against. """ - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) project, dataset = self._parse_project_and_dataset(table_loc) dataset_ref = bq.DatasetReference(project, dataset) @@ -1090,11 +1086,10 @@ def drop_table( self, name: str, *, - schema: str | None = None, database: tuple[str | str] | str | None = None, force: bool = False, ) -> None: - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) catalog, db = self._to_catalog_db_tuple(table_loc) stmt = sge.Drop( kind="TABLE", @@ -1112,11 +1107,10 @@ def create_view( name: str, obj: ir.Table, *, - schema: str | None = None, database: str | None = None, overwrite: bool = False, ) -> ir.Table: - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) catalog, db = self._to_catalog_db_tuple(table_loc) stmt = sge.Create( @@ -1137,11 +1131,10 @@ def drop_view( self, name: str, *, - schema: str | None = None, database: str | None = None, force: bool = False, ) -> None: - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) catalog, db = self._to_catalog_db_tuple(table_loc) stmt = sge.Drop( @@ -1169,32 +1162,6 @@ def _register_udfs(self, expr: ir.Expr) -> None: def _safe_raw_sql(self, *args, **kwargs): yield self.raw_sql(*args, **kwargs) - # TODO: remove when the schema kwarg is removed - def _warn_and_create_table_loc(self, database=None, schema=None): - if schema is not None: - self._warn_schema() - if database is not None and schema is not None: - if isinstance(database, str): - table_loc = f"{database}.{schema}" - elif isinstance(database, tuple): - table_loc = database + schema - elif schema is not None: - table_loc = schema - elif database is not None: - table_loc = database - else: - table_loc = None - - table_loc = self._to_sqlglot_table(table_loc) - - if table_loc is not None: - if (sg_cat := table_loc.args["catalog"]) is not None: - sg_cat.args["quoted"] = False - if (sg_db := table_loc.args["db"]) is not None: - sg_db.args["quoted"] = False - - return table_loc - def compile(expr, params=None, **kwargs): """Compile an expression for BigQuery.""" diff --git a/ibis/backends/datafusion/__init__.py b/ibis/backends/datafusion/__init__.py index 0570f163e9f99..9b299d44c301f 100644 --- a/ibis/backends/datafusion/__init__.py +++ b/ibis/backends/datafusion/__init__.py @@ -674,8 +674,10 @@ def create_table( return self.table(name, database=database) def truncate_table( - self, name: str, database: str | None = None, schema: str | None = None - ) -> None: + self, + name: str, + database: str | None = None, + ): """Delete all rows from a table. Parameters @@ -684,14 +686,12 @@ def truncate_table( Table name database Database name - schema - Schema name """ # datafusion doesn't support `TRUNCATE TABLE` so we use `DELETE FROM` # # however datafusion as of 34.0.0 doesn't implement DELETE DML yet - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) catalog, db = self._to_catalog_db_tuple(table_loc) ident = sg.table(name, db=db, catalog=catalog).sql(self.dialect) diff --git a/ibis/backends/duckdb/__init__.py b/ibis/backends/duckdb/__init__.py index bb4d4f7aa9fdd..1c53ebf29ff19 100644 --- a/ibis/backends/duckdb/__init__.py +++ b/ibis/backends/duckdb/__init__.py @@ -232,17 +232,13 @@ def create_table( return self.table(name, database=(catalog, database)) - def table( - self, name: str, schema: str | None = None, database: str | None = None - ) -> ir.Table: + def table(self, name: str, database: str | None = None) -> ir.Table: """Construct a table expression. Parameters ---------- name Table name - schema - [deprecated] Schema name database Database name @@ -252,7 +248,7 @@ def table( Table expression """ - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) # TODO: set these to better defaults catalog = table_loc.catalog or None @@ -987,7 +983,6 @@ def list_tables( self, like: str | None = None, database: tuple[str, str] | str | None = None, - schema: str | None = None, ) -> list[str]: """List tables and views. @@ -1015,8 +1010,6 @@ def list_tables( To specify a table in a separate catalog, you can pass in the catalog and database as a string `"catalog.database"`, or as a tuple of strings `("catalog", "database")`. - schema - [deprecated] Schema name. If not passed, uses the current schema. Returns ------- @@ -1042,7 +1035,7 @@ def list_tables( ['baz'] """ - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) catalog = table_loc.catalog or self.current_catalog database = table_loc.db or self.current_database diff --git a/ibis/backends/mssql/__init__.py b/ibis/backends/mssql/__init__.py index 3a215e1ece0bf..7970d0bfe5718 100644 --- a/ibis/backends/mssql/__init__.py +++ b/ibis/backends/mssql/__init__.py @@ -527,7 +527,6 @@ def list_tables( self, like: str | None = None, database: tuple[str, str] | str | None = None, - schema: str | None = None, ) -> list[str]: """List the tables in the database. @@ -552,10 +551,9 @@ def list_tables( To specify a table in a separate catalog, you can pass in the catalog and database as a string `"catalog.database"`, or as a tuple of strings `("catalog", "database")`. - schema - [deprecated] The schema inside `database` to perform the list against. + """ - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) catalog, db = self._to_catalog_db_tuple(table_loc) sql = ( diff --git a/ibis/backends/mysql/__init__.py b/ibis/backends/mysql/__init__.py index 664a1eff1da8d..5e69b327fca66 100644 --- a/ibis/backends/mysql/__init__.py +++ b/ibis/backends/mysql/__init__.py @@ -296,7 +296,6 @@ def raw_sql(self, query: str | sg.Expression, **kwargs: Any) -> Any: def list_tables( self, like: str | None = None, - schema: str | None = None, database: tuple[str, str] | str | None = None, ) -> list[str]: """List the tables in the database. @@ -316,27 +315,11 @@ def list_tables( ---------- like A pattern to use for listing tables. - schema - [deprecated] The schema to perform the list against. database Database to list tables from. Default behavior is to show tables in the current database (`self.current_database`). """ - if schema is not None: - self._warn_schema() - - if schema is not None and database is not None: - raise ValueError( - "Using both the `schema` and `database` kwargs is not supported. " - "`schema` is deprecated and will be removed in Ibis 10.0" - "\nUse the `database` kwarg with one of the following patterns:" - '\ndatabase="database"' - '\ndatabase=("catalog", "database")' - '\ndatabase="catalog.database"', - ) - elif schema is not None: - table_loc = schema - elif database is not None: + if database is not None: table_loc = database else: table_loc = self.current_database diff --git a/ibis/backends/oracle/__init__.py b/ibis/backends/oracle/__init__.py index 6bcfe69b95918..3736b10bfcd0e 100644 --- a/ibis/backends/oracle/__init__.py +++ b/ibis/backends/oracle/__init__.py @@ -270,7 +270,6 @@ def raw_sql(self, query: str | sg.Expression, **kwargs: Any) -> Any: def list_tables( self, like: str | None = None, - schema: str | None = None, database: tuple[str, str] | str | None = None, ) -> list[str]: """List the tables in the database. @@ -290,31 +289,17 @@ def list_tables( ---------- like A pattern to use for listing tables. - schema - [deprecated] The schema to perform the list against. database Database to list tables from. Default behavior is to show tables in the current database. """ - if schema is not None and database is not None: - raise exc.IbisInputError( - "Using both the `schema` and `database` kwargs is not supported. " - "`schema` is deprecated and will be removed in Ibis 10.0" - "\nUse the `database` kwarg with one of the following patterns:" - '\ndatabase="database"' - '\ndatabase=("catalog", "database")' - '\ndatabase="catalog.database"', - ) - if schema is not None: - # TODO: remove _warn_schema when the schema kwarg is removed - self._warn_schema() - table_loc = schema - elif database is not None: + if database is not None: table_loc = database else: table_loc = self.con.username.upper() + table_loc = self._to_sqlglot_table(table_loc) # Deeply frustrating here where if we call `convert` on `table_loc`, diff --git a/ibis/backends/postgres/__init__.py b/ibis/backends/postgres/__init__.py index 68feacd6c02c4..79507f6077bc1 100644 --- a/ibis/backends/postgres/__init__.py +++ b/ibis/backends/postgres/__init__.py @@ -302,7 +302,6 @@ def _session_temp_db(self) -> str | None: def list_tables( self, like: str | None = None, - schema: str | None = None, database: tuple[str, str] | str | None = None, ) -> list[str]: """List the tables in the database. @@ -322,27 +321,12 @@ def list_tables( ---------- like A pattern to use for listing tables. - schema - [deprecated] The schema to perform the list against. database Database to list tables from. Default behavior is to show tables in the current database. """ - if schema is not None: - self._warn_schema() - - if schema is not None and database is not None: - raise ValueError( - "Using both the `schema` and `database` kwargs is not supported. " - "`schema` is deprecated and will be removed in Ibis 10.0" - "\nUse the `database` kwarg with one of the following patterns:" - '\ndatabase="database"' - '\ndatabase=("catalog", "database")' - '\ndatabase="catalog.database"', - ) - elif schema is not None: - table_loc = schema - elif database is not None: + + if database is not None: table_loc = database else: table_loc = (self.current_catalog, self.current_database) diff --git a/ibis/backends/snowflake/__init__.py b/ibis/backends/snowflake/__init__.py index 0d62bb76f4383..9f2b7bafb0b97 100644 --- a/ibis/backends/snowflake/__init__.py +++ b/ibis/backends/snowflake/__init__.py @@ -619,7 +619,6 @@ def list_tables( self, like: str | None = None, database: tuple[str, str] | str | None = None, - schema: str | None = None, ) -> list[str]: """List the tables in the database. @@ -644,10 +643,8 @@ def list_tables( To specify a table in a separate Snowflake catalog, you can pass in the catalog and database as a string `"catalog.database"`, or as a tuple of strings `("catalog", "database")`. - schema - [deprecated] The schema inside `database` to perform the list against. """ - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) tables_query = "SHOW TABLES" views_query = "SHOW VIEWS" @@ -1181,7 +1178,6 @@ def insert( self, table_name: str, obj: pd.DataFrame | ir.Table | list | dict, - schema: str | None = None, database: str | None = None, overwrite: bool = False, ) -> None: @@ -1202,8 +1198,6 @@ def insert( The name of the table to which data needs will be inserted obj The source data or expression to insert - schema - [deprecated] The name of the schema that the table is located in database Name of the attached database that the table is located in. @@ -1214,7 +1208,7 @@ def insert( If `True` then replace existing contents of table """ - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) catalog, db = self._to_catalog_db_tuple(table_loc) if not isinstance(obj, ir.Table): diff --git a/ibis/backends/sql/__init__.py b/ibis/backends/sql/__init__.py index 2d64efe6076b9..c2e4d47d5b76d 100644 --- a/ibis/backends/sql/__init__.py +++ b/ibis/backends/sql/__init__.py @@ -25,47 +25,7 @@ from ibis.expr.schema import SchemaLike -class _DatabaseSchemaHandler: - """Temporary mixin collecting several helper functions and code snippets. - - Help to 'gracefully' deprecate the use of `schema` as a hierarchical term. - """ - - @staticmethod - def _warn_schema(): - util.warn_deprecated( - name="schema", - as_of="9.0", - removed_in="10.0", - instead="Use the `database` kwarg with one of the following patterns:" - '\ndatabase="database"' - '\ndatabase=("catalog", "database")' - '\ndatabase="catalog.database"', - # TODO: add option for namespace object - ) - - def _warn_and_create_table_loc(self, database=None, schema=None): - if schema is not None: - self._warn_schema() - - if database is not None and schema is not None: - if isinstance(database, str): - table_loc = f"{database}.{schema}" - elif isinstance(database, tuple): - table_loc = database + schema - elif schema is not None: - table_loc = schema - elif database is not None: - table_loc = database - else: - table_loc = None - - table_loc = self._to_sqlglot_table(table_loc) - - return table_loc - - -class SQLBackend(BaseBackend, _DatabaseSchemaHandler): +class SQLBackend(BaseBackend): compiler: ClassVar[SQLGlotCompiler] name: ClassVar[str] @@ -109,7 +69,6 @@ def _fetch_from_cursor(self, cursor, schema: sch.Schema) -> pd.DataFrame: def table( self, name: str, - schema: str | None = None, database: tuple[str, str] | str | None = None, ) -> ir.Table: """Construct a table expression. @@ -118,8 +77,6 @@ def table( ---------- name Table name - schema - [deprecated] Schema name database Database name @@ -129,7 +86,7 @@ def table( Table expression """ - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) catalog = table_loc.catalog or None database = table_loc.db or None @@ -218,10 +175,9 @@ def create_view( obj: ir.Table, *, database: str | None = None, - schema: str | None = None, overwrite: bool = False, ) -> ir.Table: - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) catalog, db = self._to_catalog_db_tuple(table_loc) src = sge.Create( @@ -240,10 +196,9 @@ def drop_view( name: str, *, database: str | None = None, - schema: str | None = None, force: bool = False, ) -> None: - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) catalog, db = self._to_catalog_db_tuple(table_loc) src = sge.Drop( @@ -281,7 +236,7 @@ def drop_table( database: tuple[str, str] | str | None = None, force: bool = False, ) -> None: - table_loc = self._warn_and_create_table_loc(database, None) + table_loc = self._to_sqlglot_table(database) catalog, db = self._to_catalog_db_tuple(table_loc) drop_stmt = sg.exp.Drop( @@ -358,7 +313,6 @@ def insert( self, table_name: str, obj: pd.DataFrame | ir.Table | list | dict, - schema: str | None = None, database: str | None = None, overwrite: bool = False, ) -> None: @@ -381,8 +335,6 @@ def insert( The name of the table to which data needs will be inserted obj The source data or expression to insert - schema - [deprecated] The name of the schema that the table is located in database Name of the attached database that the table is located in. @@ -393,7 +345,7 @@ def insert( If `True` then replace existing contents of table """ - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) catalog, db = self._to_catalog_db_tuple(table_loc) if overwrite: @@ -485,7 +437,9 @@ def _build_insert_template( ).sql(self.dialect) def truncate_table( - self, name: str, database: str | None = None, schema: str | None = None + self, + name: str, + database: str | None = None, ) -> None: """Delete all rows from a table. @@ -509,11 +463,10 @@ def truncate_table( For backends that support multi-level table hierarchies, you can pass in a dotted string path like `"catalog.database"` or a tuple of strings like `("catalog", "database")`. - schema - [deprecated] Schema name + """ - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) catalog, db = self._to_catalog_db_tuple(table_loc) ident = sg.table(name, db=db, catalog=catalog, quoted=self.compiler.quoted).sql( diff --git a/ibis/backends/sqlite/__init__.py b/ibis/backends/sqlite/__init__.py index a1f4f078178db..a5c074aefbd86 100644 --- a/ibis/backends/sqlite/__init__.py +++ b/ibis/backends/sqlite/__init__.py @@ -560,13 +560,8 @@ def create_view( obj: ir.Table, *, database: str | None = None, - schema: str | None = None, overwrite: bool = False, ) -> ir.Table: - # schema was never used here, but warn for consistency - if schema is not None: - self._warn_schema() - view = sg.table(name, catalog=database, quoted=self.compiler.quoted) stmts = [] diff --git a/ibis/backends/trino/__init__.py b/ibis/backends/trino/__init__.py index 61c3c9a4b2237..6bf01c2a6bc82 100644 --- a/ibis/backends/trino/__init__.py +++ b/ibis/backends/trino/__init__.py @@ -213,7 +213,6 @@ def list_tables( self, like: str | None = None, database: tuple[str, str] | str | None = None, - schema: str | None = None, ) -> list[str]: """List the tables in the database. @@ -230,10 +229,8 @@ def list_tables( To specify a table in a separate catalog, you can pass in the catalog and database as a string `"catalog.database"`, or as a tuple of strings `("catalog", "database")`. - schema - [deprecated] The schema inside `database` to perform the list against. """ - table_loc = self._warn_and_create_table_loc(database, schema) + table_loc = self._to_sqlglot_table(database) query = "SHOW TABLES"