diff --git a/doc/source/whatsnew/v1.5.1.rst b/doc/source/whatsnew/v1.5.1.rst index da0bd746e3da58..d61a8f720a0b4b 100644 --- a/doc/source/whatsnew/v1.5.1.rst +++ b/doc/source/whatsnew/v1.5.1.rst @@ -74,7 +74,7 @@ Fixed regressions - Regression in :func:`.read_csv` causing an ``EmptyDataError`` when using an UTF-8 file handle that was already read from (:issue:`48646`) - Fixed regression in :meth:`DataFrame.plot` ignoring invalid ``colormap`` for ``kind="scatter"`` (:issue:`48726`) - Fixed performance regression in :func:`factorize` when ``na_sentinel`` is not ``None`` and ``sort=False`` (:issue:`48620`) -- +- Fixed regression causing an ``AttributeError`` during warning emitted if the provided table name in :meth:`DataFrame.to_sql` and the table name actually used in the database do not match (:issue:`48733`) .. --------------------------------------------------------------------------- diff --git a/pandas/io/sql.py b/pandas/io/sql.py index 9beafb90326767..f5ad0787ff8df6 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -1635,8 +1635,8 @@ def prep_table( def check_case_sensitive( self, - name, - schema, + name: str, + schema: str | None, ) -> None: """ Checks table name for issues with case-sensitivity. @@ -1645,10 +1645,10 @@ def check_case_sensitive( if not name.isdigit() and not name.islower(): # check for potentially case sensitivity issues (GH7815) # Only check when name is not a number and name is not lower case - from sqlalchemy import inspect + from sqlalchemy import inspect as sqlalchemy_inspect with self.connectable.connect() as conn: - insp = inspect(conn) + insp = sqlalchemy_inspect(conn) table_names = insp.get_table_names(schema=schema or self.meta.schema) if name not in table_names: msg = ( @@ -1666,11 +1666,11 @@ def check_case_sensitive( def to_sql( self, frame, - name, + name: str, if_exists: Literal["fail", "replace", "append"] = "fail", index: bool = True, index_label=None, - schema=None, + schema: str | None = None, chunksize=None, dtype: DtypeArg | None = None, method=None, @@ -1757,9 +1757,9 @@ def tables(self): return self.meta.tables def has_table(self, name: str, schema: str | None = None): - from sqlalchemy import inspect + from sqlalchemy import inspect as sqlalchemy_inspect - insp = inspect(self.connectable) + insp = sqlalchemy_inspect(self.connectable) return insp.has_table(name, schema or self.meta.schema) def get_table(self, table_name: str, schema: str | None = None) -> Table: diff --git a/pandas/tests/io/test_sql.py b/pandas/tests/io/test_sql.py index ee55837324f20e..1bfb85f369415f 100644 --- a/pandas/tests/io/test_sql.py +++ b/pandas/tests/io/test_sql.py @@ -1357,10 +1357,17 @@ def test_not_reflect_all_tables(self): def test_warning_case_insensitive_table_name(self, test_frame1): # see gh-7815 - # - # We can't test that this warning is triggered, a the database - # configuration would have to be altered. But here we test that - # the warning is certainly NOT triggered in a normal case. + with tm.assert_produces_warning( + UserWarning, + match=( + r"The provided table name 'TABLE1' is not found exactly as such in " + r"the database after writing the table, possibly due to case " + r"sensitivity issues. Consider using lower case table names." + ), + ): + sql.SQLDatabase(self.conn).check_case_sensitive("TABLE1", "") + + # Test that the warning is certainly NOT triggered in a normal case. with tm.assert_produces_warning(None): test_frame1.to_sql("CaseSensitive", self.conn)