From 6cab5894026834ca1499a1b6caa6895d14884d78 Mon Sep 17 00:00:00 2001 From: lzieglerpenn Date: Wed, 26 Apr 2023 18:52:30 -0400 Subject: [PATCH 01/13] add truncate option for to_sql method --- pandas/io/sql.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/pandas/io/sql.py b/pandas/io/sql.py index d7f7a0b8801ed..01f40f0fd0242 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -679,7 +679,7 @@ def to_sql( name: str, con, schema: str | None = None, - if_exists: Literal["fail", "replace", "append"] = "fail", + if_exists: Literal["fail", "replace", "append", "truncate"] = "fail", index: bool = True, index_label: IndexLabel = None, chunksize: int | None = None, @@ -704,10 +704,11 @@ def to_sql( schema : str, optional Name of SQL schema in database to write to (if database flavor supports this). If None, use default schema (default). - if_exists : {'fail', 'replace', 'append'}, default 'fail' + if_exists : {'fail', 'replace', 'append', 'truncate'}, default 'fail' - fail: If table exists, do nothing. - replace: If table exists, drop it, recreate it, and insert data. - append: If table exists, insert data. Create if does not exist. + - truncate: If table exists, truncate the table, then insert data. index : bool, default True Write DataFrame index as a column. index_label : str or sequence, optional @@ -757,7 +758,7 @@ def to_sql( `sqlite3 `__ or `SQLAlchemy `__ """ # noqa:E501 - if if_exists not in ("fail", "replace", "append"): + if if_exists not in ("fail", "replace", "append", "truncate"): raise ValueError(f"'{if_exists}' is not valid for if_exists") if isinstance(frame, Series): @@ -860,7 +861,7 @@ def __init__( pandas_sql_engine, frame=None, index: bool | str | list[str] | None = True, - if_exists: Literal["fail", "replace", "append"] = "fail", + if_exists: Literal["fail", "replace", "append", "truncate"] = "fail", prefix: str = "pandas", index_label=None, schema=None, @@ -911,6 +912,8 @@ def create(self) -> None: if self.if_exists == "replace": self.pd_sql.drop_table(self.name, self.schema) self._execute_create() + elif self.if_exists == "truncate": + self.pd_sql.trunc_table(self.name, self.schema) elif self.if_exists == "append": pass else: @@ -1399,7 +1402,7 @@ def to_sql( self, frame, name: str, - if_exists: Literal["fail", "replace", "append"] = "fail", + if_exists: Literal["fail", "replace", "append", "truncate"] = "fail", index: bool = True, index_label=None, schema=None, @@ -1860,7 +1863,7 @@ def to_sql( self, frame, name: str, - if_exists: Literal["fail", "replace", "append"] = "fail", + if_exists: Literal["fail", "replace", "append", "truncate"] = "fail", index: bool = True, index_label=None, schema: str | None = None, @@ -1878,7 +1881,7 @@ def to_sql( frame : DataFrame name : string Name of SQL table. - if_exists : {'fail', 'replace', 'append'}, default 'fail' + if_exists : {'fail', 'replace', 'append', 'truncate'}, default 'fail' - fail: If table exists, do nothing. - replace: If table exists, drop it, recreate it, and insert data. - append: If table exists, insert data. Create if does not exist. @@ -2333,10 +2336,11 @@ def to_sql( frame: DataFrame name: string Name of SQL table. - if_exists: {'fail', 'replace', 'append'}, default 'fail' + if_exists: {'fail', 'replace', 'append', 'truncate'}, default 'fail' fail: If table exists, do nothing. replace: If table exists, drop it, recreate it, and insert data. append: If table exists, insert data. Create if it does not exist. + truncate: If table exists, truncate the table, then insert data. index : bool, default True Write DataFrame index as a column index_label : string or sequence, default None From 5329c101a74a5151d9d19daf6e50c6ff5b628a76 Mon Sep 17 00:00:00 2001 From: lzieglerpenn Date: Wed, 26 Apr 2023 18:52:52 -0400 Subject: [PATCH 02/13] add enhancement to release notes --- doc/source/whatsnew/v2.1.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v2.1.0.rst b/doc/source/whatsnew/v2.1.0.rst index b10dd876050ae..1e778fbc16918 100644 --- a/doc/source/whatsnew/v2.1.0.rst +++ b/doc/source/whatsnew/v2.1.0.rst @@ -96,7 +96,7 @@ Other enhancements - Let :meth:`DataFrame.to_feather` accept a non-default :class:`Index` and non-string column names (:issue:`51787`) - Performance improvement in :func:`read_csv` (:issue:`52632`) with ``engine="c"`` - Performance improvement in :func:`concat` with homogeneous ``np.float64`` or ``np.float32`` dtypes (:issue:`52685`) -- +- Added ``"truncate"`` option to ``if_exists`` argument in :meth:`DataFrame.to_sql` which truncates the existing table before inserting new data (:issue:`37210`). .. --------------------------------------------------------------------------- .. _whatsnew_210.notable_bug_fixes: From 68aeec65b7f6b533c2dd3557c48e0aa34efb3dce Mon Sep 17 00:00:00 2001 From: lzieglerpenn Date: Wed, 26 Apr 2023 18:57:02 -0400 Subject: [PATCH 03/13] add test for new option --- pandas/tests/io/test_sql.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pandas/tests/io/test_sql.py b/pandas/tests/io/test_sql.py index 035fda29f8ffb..61db52e7688d8 100644 --- a/pandas/tests/io/test_sql.py +++ b/pandas/tests/io/test_sql.py @@ -1104,6 +1104,17 @@ def test_to_sql_replace(self, test_frame1): assert num_rows == num_entries + def test_to_sql_truncate(self, test_frame1): + sql.to_sql(test_frame1, "test_frame3", self.conn, if_exists="fail") + # Add to table again + sql.to_sql(test_frame1, "test_frame3", self.conn, if_exists="truncate") + assert sql.has_table("test_frame3", self.conn) + + num_entries = len(test_frame1) + num_rows = count_rows(self.conn, "test_frame3") + + assert num_rows == num_entries + def test_to_sql_append(self, test_frame1): assert sql.to_sql(test_frame1, "test_frame4", self.conn, if_exists="fail") == 4 From 0e8e6f724e7e40273e06e980cb4158d4f09c68d8 Mon Sep 17 00:00:00 2001 From: lzieglerpenn Date: Thu, 27 Apr 2023 10:54:03 -0400 Subject: [PATCH 04/13] alphabetize release notes --- doc/source/whatsnew/v2.1.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v2.1.0.rst b/doc/source/whatsnew/v2.1.0.rst index 1e778fbc16918..71a3dd4c8586c 100644 --- a/doc/source/whatsnew/v2.1.0.rst +++ b/doc/source/whatsnew/v2.1.0.rst @@ -83,6 +83,7 @@ Other enhancements - :meth:`arrays.DatetimeArray.map`, :meth:`arrays.TimedeltaArray.map` and :meth:`arrays.PeriodArray.map` can now take a ``na_action`` argument (:issue:`51644`) - :meth:`arrays.SparseArray.map` now supports ``na_action`` (:issue:`52096`). - Add :meth:`diff()` and :meth:`round()` for :class:`Index` (:issue:`19708`) +- Add ``"truncate"`` option to ``if_exists`` argument in :meth:`DataFrame.to_sql` which truncates the existing table before inserting new data (:issue:`37210`). - Add dtype of categories to ``repr`` information of :class:`CategoricalDtype` (:issue:`52179`) - Added to the escape mode "latex-math" preserving without escaping all characters between "\(" and "\)" in formatter (:issue:`51903`) - Adding ``engine_kwargs`` parameter to :meth:`DataFrame.read_excel` (:issue:`52214`) @@ -96,7 +97,6 @@ Other enhancements - Let :meth:`DataFrame.to_feather` accept a non-default :class:`Index` and non-string column names (:issue:`51787`) - Performance improvement in :func:`read_csv` (:issue:`52632`) with ``engine="c"`` - Performance improvement in :func:`concat` with homogeneous ``np.float64`` or ``np.float32`` dtypes (:issue:`52685`) -- Added ``"truncate"`` option to ``if_exists`` argument in :meth:`DataFrame.to_sql` which truncates the existing table before inserting new data (:issue:`37210`). .. --------------------------------------------------------------------------- .. _whatsnew_210.notable_bug_fixes: From 7a323dcdab678bc0f07f9f1971a2dbeeb9ee5e33 Mon Sep 17 00:00:00 2001 From: lzieglerpenn Date: Thu, 27 Apr 2023 11:38:27 -0400 Subject: [PATCH 05/13] add truncate option to prep_table --- pandas/io/sql.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/io/sql.py b/pandas/io/sql.py index 01f40f0fd0242..73f7a0137638b 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -1786,7 +1786,7 @@ def prep_table( self, frame, name: str, - if_exists: Literal["fail", "replace", "append"] = "fail", + if_exists: Literal["fail", "replace", "append", "truncate"] = "fail", index: bool | str | list[str] | None = True, index_label=None, schema=None, @@ -1885,6 +1885,7 @@ def to_sql( - fail: If table exists, do nothing. - replace: If table exists, drop it, recreate it, and insert data. - append: If table exists, insert data. Create if does not exist. + - truncate: If table exists, truncate the table, then insert data. index : boolean, default True Write DataFrame index as a column. index_label : string or sequence, default None From af8e74ba28bbfe607d0de464ed1413ec5df8057a Mon Sep 17 00:00:00 2001 From: lzieglerpenn Date: Thu, 27 Apr 2023 13:12:54 -0400 Subject: [PATCH 06/13] add trunc_table func and rmv from sqlite --- pandas/io/sql.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pandas/io/sql.py b/pandas/io/sql.py index 73f7a0137638b..d464b8be070ca 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -1979,6 +1979,13 @@ def drop_table(self, table_name: str, schema: str | None = None) -> None: with self.run_transaction(): self.get_table(table_name, schema).drop(bind=self.con) self.meta.clear() + + def trunc_table(self, table_name: str, schema: str | None = None) -> None: + schema = schema or self.meta.schema + if self.has_table(table_name, schema): + self.meta.reflect(bind=self.con, only=[table_name], schema=schema) + self.execute(f"TRUNCATE TABLE {schema}.{table_name}") + self.meta.clear() def _create_sql_schema( self, @@ -2337,11 +2344,10 @@ def to_sql( frame: DataFrame name: string Name of SQL table. - if_exists: {'fail', 'replace', 'append', 'truncate'}, default 'fail' + if_exists: {'fail', 'replace', 'append'}, default 'fail' fail: If table exists, do nothing. replace: If table exists, drop it, recreate it, and insert data. append: If table exists, insert data. Create if it does not exist. - truncate: If table exists, truncate the table, then insert data. index : bool, default True Write DataFrame index as a column index_label : string or sequence, default None From 3bf6757d04241413cc24e5927f336d05b17e8805 Mon Sep 17 00:00:00 2001 From: lzieglerpenn Date: Thu, 27 Apr 2023 13:50:28 -0400 Subject: [PATCH 07/13] update test --- pandas/tests/io/test_sql.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/pandas/tests/io/test_sql.py b/pandas/tests/io/test_sql.py index 61db52e7688d8..8b1b55550cc01 100644 --- a/pandas/tests/io/test_sql.py +++ b/pandas/tests/io/test_sql.py @@ -1104,17 +1104,6 @@ def test_to_sql_replace(self, test_frame1): assert num_rows == num_entries - def test_to_sql_truncate(self, test_frame1): - sql.to_sql(test_frame1, "test_frame3", self.conn, if_exists="fail") - # Add to table again - sql.to_sql(test_frame1, "test_frame3", self.conn, if_exists="truncate") - assert sql.has_table("test_frame3", self.conn) - - num_entries = len(test_frame1) - num_rows = count_rows(self.conn, "test_frame3") - - assert num_rows == num_entries - def test_to_sql_append(self, test_frame1): assert sql.to_sql(test_frame1, "test_frame4", self.conn, if_exists="fail") == 4 @@ -2223,6 +2212,23 @@ def _get_index_columns(self, tbl_name): def test_to_sql_save_index(self): self._to_sql_save_index() + def test_to_sql_truncate(self, test_frame1): + if self.flavor == "sqlite": + with pytest.raises(Exception): + sql.to_sql( + test_frame1, "test_frame3", self.conn, if_exists="truncate" + ) + else: + sql.to_sql(test_frame1, "test_frame3", self.conn, if_exists="fail") + # Add to table again + sql.to_sql(test_frame1, "test_frame3", self.conn, if_exists="truncate") + assert sql.has_table("test_frame3", self.conn) + + num_entries = len(test_frame1) + num_rows = count_rows(self.conn, "test_frame3") + + assert num_rows == num_entries + def test_transactions(self): self._transaction_test() From 78d2d67708dbed201f68698edcdc990a4b81513b Mon Sep 17 00:00:00 2001 From: lzieglerpenn Date: Thu, 27 Apr 2023 14:39:03 -0400 Subject: [PATCH 08/13] SQLite error handling --- pandas/io/sql.py | 5 ++++- pandas/tests/io/test_sql.py | 7 +++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/pandas/io/sql.py b/pandas/io/sql.py index d464b8be070ca..87ca4ba979f54 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -1979,7 +1979,7 @@ def drop_table(self, table_name: str, schema: str | None = None) -> None: with self.run_transaction(): self.get_table(table_name, schema).drop(bind=self.con) self.meta.clear() - + def trunc_table(self, table_name: str, schema: str | None = None) -> None: schema = schema or self.meta.schema if self.has_table(table_name, schema): @@ -2415,6 +2415,9 @@ def drop_table(self, name: str, schema: str | None = None) -> None: drop_sql = f"DROP TABLE {_get_valid_sqlite_name(name)}" self.execute(drop_sql) + def trunc_table(self, name: str, schema: str | None = None) -> None: + raise NotImplementedError("TRUNCATE not implemented on 'SQLiteDatabase'") + def _create_sql_schema( self, frame, diff --git a/pandas/tests/io/test_sql.py b/pandas/tests/io/test_sql.py index 8b1b55550cc01..e299318bd457b 100644 --- a/pandas/tests/io/test_sql.py +++ b/pandas/tests/io/test_sql.py @@ -2214,10 +2214,9 @@ def test_to_sql_save_index(self): def test_to_sql_truncate(self, test_frame1): if self.flavor == "sqlite": - with pytest.raises(Exception): - sql.to_sql( - test_frame1, "test_frame3", self.conn, if_exists="truncate" - ) + msg = "TRUNCATE not implemented on 'SQLiteDatabase'" + with pytest.raises(NotImplementedError, match=msg): + sql.to_sql(test_frame1, "test_frame3", self.conn, if_exists="truncate") else: sql.to_sql(test_frame1, "test_frame3", self.conn, if_exists="fail") # Add to table again From 5df0593f1cff5d196cdecd06592b8ac04d4db033 Mon Sep 17 00:00:00 2001 From: lzieglerpenn Date: Thu, 27 Apr 2023 15:31:19 -0400 Subject: [PATCH 09/13] fix and add tests --- pandas/io/sql.py | 2 ++ pandas/tests/io/test_sql.py | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/pandas/io/sql.py b/pandas/io/sql.py index 87ca4ba979f54..ad94ccb362297 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -1982,6 +1982,8 @@ def drop_table(self, table_name: str, schema: str | None = None) -> None: def trunc_table(self, table_name: str, schema: str | None = None) -> None: schema = schema or self.meta.schema + if schema == None: + raise NotImplementedError("TRUNCATE not supported on database.") if self.has_table(table_name, schema): self.meta.reflect(bind=self.con, only=[table_name], schema=schema) self.execute(f"TRUNCATE TABLE {schema}.{table_name}") diff --git a/pandas/tests/io/test_sql.py b/pandas/tests/io/test_sql.py index e299318bd457b..ac73012468491 100644 --- a/pandas/tests/io/test_sql.py +++ b/pandas/tests/io/test_sql.py @@ -1104,6 +1104,13 @@ def test_to_sql_replace(self, test_frame1): assert num_rows == num_entries + def test_sqlite_truncate_raises(self, test_frame1): + msg = "TRUNCATE not implemented on 'SQLiteDatabase'" + with pytest.raises(NotImplementedError, match=msg): + sql.to_sql( + test_frame1, "test_frame3", self.conn, if_exists="truncate" + ) + def test_to_sql_append(self, test_frame1): assert sql.to_sql(test_frame1, "test_frame4", self.conn, if_exists="fail") == 4 @@ -2214,7 +2221,7 @@ def test_to_sql_save_index(self): def test_to_sql_truncate(self, test_frame1): if self.flavor == "sqlite": - msg = "TRUNCATE not implemented on 'SQLiteDatabase'" + msg = "TRUNCATE not supported on database." with pytest.raises(NotImplementedError, match=msg): sql.to_sql(test_frame1, "test_frame3", self.conn, if_exists="truncate") else: From 2fdd7476e3e51002b0b690cde4d6a53d393e3ea3 Mon Sep 17 00:00:00 2001 From: lzieglerpenn Date: Fri, 28 Apr 2023 11:31:52 -0400 Subject: [PATCH 10/13] better sqlite errors and tests --- pandas/io/sql.py | 10 ++++++---- pandas/tests/io/test_sql.py | 14 +++++++++----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/pandas/io/sql.py b/pandas/io/sql.py index ad94ccb362297..dcca970217a8c 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -1982,11 +1982,13 @@ def drop_table(self, table_name: str, schema: str | None = None) -> None: def trunc_table(self, table_name: str, schema: str | None = None) -> None: schema = schema or self.meta.schema - if schema == None: - raise NotImplementedError("TRUNCATE not supported on database.") + if self.con.engine.driver == 'pysqlite': + raise NotImplementedError("TRUNCATE not supported on sqlite database.") if self.has_table(table_name, schema): self.meta.reflect(bind=self.con, only=[table_name], schema=schema) - self.execute(f"TRUNCATE TABLE {schema}.{table_name}") + with self.run_transaction(): + table_to_truncate = self.get_table(table_name, schema) + self.execute(f"TRUNCATE TABLE {table_to_truncate}") self.meta.clear() def _create_sql_schema( @@ -2418,7 +2420,7 @@ def drop_table(self, name: str, schema: str | None = None) -> None: self.execute(drop_sql) def trunc_table(self, name: str, schema: str | None = None) -> None: - raise NotImplementedError("TRUNCATE not implemented on 'SQLiteDatabase'") + raise NotImplementedError("TRUNCATE not supported on sqlite database.") def _create_sql_schema( self, diff --git a/pandas/tests/io/test_sql.py b/pandas/tests/io/test_sql.py index ac73012468491..eafda7861edcb 100644 --- a/pandas/tests/io/test_sql.py +++ b/pandas/tests/io/test_sql.py @@ -1105,11 +1105,12 @@ def test_to_sql_replace(self, test_frame1): assert num_rows == num_entries def test_sqlite_truncate_raises(self, test_frame1): - msg = "TRUNCATE not implemented on 'SQLiteDatabase'" + msg = 'TRUNCATE not supported on sqlite database.' with pytest.raises(NotImplementedError, match=msg): - sql.to_sql( - test_frame1, "test_frame3", self.conn, if_exists="truncate" - ) + # create table + sql.to_sql(test_frame1, "test_frame3", self.conn, if_exists="fail") + # Add to table again + sql.to_sql(test_frame1, "test_frame3", self.conn, if_exists="truncate") def test_to_sql_append(self, test_frame1): assert sql.to_sql(test_frame1, "test_frame4", self.conn, if_exists="fail") == 4 @@ -2221,8 +2222,11 @@ def test_to_sql_save_index(self): def test_to_sql_truncate(self, test_frame1): if self.flavor == "sqlite": - msg = "TRUNCATE not supported on database." + msg = 'TRUNCATE not supported on sqlite database.' with pytest.raises(NotImplementedError, match=msg): + # create table + sql.to_sql(test_frame1, "test_frame3", self.conn, if_exists="fail") + # Add to table again sql.to_sql(test_frame1, "test_frame3", self.conn, if_exists="truncate") else: sql.to_sql(test_frame1, "test_frame3", self.conn, if_exists="fail") From 17fec16a3ece870351f806c1a27ba730f53a23fe Mon Sep 17 00:00:00 2001 From: lzieglerpenn Date: Fri, 28 Apr 2023 12:08:50 -0400 Subject: [PATCH 11/13] check engine name instead of driver --- pandas/io/sql.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/io/sql.py b/pandas/io/sql.py index dcca970217a8c..b882c1cf5c535 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -1982,7 +1982,7 @@ def drop_table(self, table_name: str, schema: str | None = None) -> None: def trunc_table(self, table_name: str, schema: str | None = None) -> None: schema = schema or self.meta.schema - if self.con.engine.driver == 'pysqlite': + if self.con.engine.name == 'sqlite': raise NotImplementedError("TRUNCATE not supported on sqlite database.") if self.has_table(table_name, schema): self.meta.reflect(bind=self.con, only=[table_name], schema=schema) From df9f2e232867354e86693824fca51aa099b8b3fb Mon Sep 17 00:00:00 2001 From: lzieglerpenn Date: Fri, 28 Apr 2023 12:14:05 -0400 Subject: [PATCH 12/13] pre-commit updates --- pandas/io/sql.py | 2 +- pandas/tests/io/test_sql.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/io/sql.py b/pandas/io/sql.py index b882c1cf5c535..9d80469192e22 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -1982,7 +1982,7 @@ def drop_table(self, table_name: str, schema: str | None = None) -> None: def trunc_table(self, table_name: str, schema: str | None = None) -> None: schema = schema or self.meta.schema - if self.con.engine.name == 'sqlite': + if self.con.engine.name == "sqlite": raise NotImplementedError("TRUNCATE not supported on sqlite database.") if self.has_table(table_name, schema): self.meta.reflect(bind=self.con, only=[table_name], schema=schema) diff --git a/pandas/tests/io/test_sql.py b/pandas/tests/io/test_sql.py index eafda7861edcb..695cef5921dcf 100644 --- a/pandas/tests/io/test_sql.py +++ b/pandas/tests/io/test_sql.py @@ -1105,7 +1105,7 @@ def test_to_sql_replace(self, test_frame1): assert num_rows == num_entries def test_sqlite_truncate_raises(self, test_frame1): - msg = 'TRUNCATE not supported on sqlite database.' + msg = "TRUNCATE not supported on sqlite database." with pytest.raises(NotImplementedError, match=msg): # create table sql.to_sql(test_frame1, "test_frame3", self.conn, if_exists="fail") @@ -2222,7 +2222,7 @@ def test_to_sql_save_index(self): def test_to_sql_truncate(self, test_frame1): if self.flavor == "sqlite": - msg = 'TRUNCATE not supported on sqlite database.' + msg = "TRUNCATE not supported on sqlite database." with pytest.raises(NotImplementedError, match=msg): # create table sql.to_sql(test_frame1, "test_frame3", self.conn, if_exists="fail") From 7c1e0d76539dc6d4243f716467fa55cea4e89a40 Mon Sep 17 00:00:00 2001 From: lzieglerpenn Date: Thu, 18 May 2023 08:20:52 -0400 Subject: [PATCH 13/13] add space back in (conflict res error) --- pandas/io/sql.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/io/sql.py b/pandas/io/sql.py index 0e4f6fca3ee33..8087453810d7c 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -761,7 +761,7 @@ def to_sql( rows as stipulated in the `sqlite3 `__ or `SQLAlchemy `__ - """ # noqa:E501 + """ # noqa: E501 if if_exists not in ("fail", "replace", "append", "truncate"): raise ValueError(f"'{if_exists}' is not valid for if_exists")