Backport PR #54750 on branch 2.1.x (Revert deprecation of con as keyword only arg)
diff --git a/doc/source/whatsnew/v2.1.0.rst b/doc/source/whatsnew/v2.1.0.rst
index e3f18067e354d..f5758a079b1b5 100644
--- a/doc/source/whatsnew/v2.1.0.rst
+++ b/doc/source/whatsnew/v2.1.0.rst
@@ -586,7 +586,7 @@ Other Deprecations
 - Deprecated the use of non-supported datetime64 and timedelta64 resolutions with :func:`pandas.array`. Supported resolutions are: "s", "ms", "us", "ns" resolutions (:issue:`53058`)
 - Deprecated values ``"pad"``, ``"ffill"``, ``"bfill"``, ``"backfill"`` for :meth:`Series.interpolate` and :meth:`DataFrame.interpolate`, use ``obj.ffill()`` or ``obj.bfill()`` instead (:issue:`53581`)
 - Deprecated the behavior of :meth:`Index.argmax`, :meth:`Index.argmin`, :meth:`Series.argmax`, :meth:`Series.argmin` with either all-NAs and ``skipna=True`` or any-NAs and ``skipna=False`` returning -1; in a future version this will raise ``ValueError`` (:issue:`33941`, :issue:`33942`)
-- Deprecated allowing non-keyword arguments in :meth:`DataFrame.to_sql` except ``name`` (:issue:`54229`)
+- Deprecated allowing non-keyword arguments in :meth:`DataFrame.to_sql` except ``name`` and ``con`` (:issue:`54229`)
 
 .. ---------------------------------------------------------------------------
 .. _whatsnew_210.performance:
diff --git a/pandas/core/generic.py b/pandas/core/generic.py
index 09ebd9387220f..b4281f6959997 100644
--- a/pandas/core/generic.py
+++ b/pandas/core/generic.py
@@ -2796,7 +2796,7 @@ def to_hdf(
 
     @final
     @deprecate_nonkeyword_arguments(
-        version="3.0", allowed_args=["self", "name"], name="to_sql"
+        version="3.0", allowed_args=["self", "name", "con"], name="to_sql"
     )
     def to_sql(
         self,
diff --git a/pandas/tests/io/test_sql.py b/pandas/tests/io/test_sql.py
index 2f446e6b8c81d..9ec0ba0b12a76 100644
--- a/pandas/tests/io/test_sql.py
+++ b/pandas/tests/io/test_sql.py
@@ -2849,13 +2849,14 @@ def setup_driver(cls):
     def test_keyword_deprecation(self):
         # GH 54397
         msg = (
-            "tarting with pandas version 3.0 all arguments of to_sql except for the "
-            "argument 'name' will be keyword-only."
+            "Starting with pandas version 3.0 all arguments of to_sql except for the "
+            "arguments 'name' and 'con' will be keyword-only."
         )
         df = DataFrame([{"A": 1, "B": 2, "C": 3}, {"A": 1, "B": 2, "C": 3}])
+        df.to_sql("example", self.conn)
 
         with tm.assert_produces_warning(FutureWarning, match=msg):
-            df.to_sql("example", self.conn)
+            df.to_sql("example", self.conn, None, if_exists="replace")
 
     def test_default_type_conversion(self):
         df = sql.read_sql_table("types", self.conn)

Backport PR #54750: Revert deprecation of con as keyword only arg