Skip to content

Fixing multi method for to_sql for non-oracle databases #57311

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Feb 17, 2024
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.2.1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Fixed regressions
- Fixed regression in :meth:`Index.join` raising ``TypeError`` when joining an empty index to a non-empty index containing mixed dtype values (:issue:`57048`)
- Fixed regression in :meth:`Series.pct_change` raising a ``ValueError`` for an empty :class:`Series` (:issue:`57056`)
- Fixed regression in :meth:`Series.to_numpy` when dtype is given as float and the data contains NaNs (:issue:`57121`)
- Fixed regression in :meth:`DataFrame.to_sql` when method="multi" is passed and the dialect type is not Oracle (:issue:`57310`)

.. ---------------------------------------------------------------------------
.. _whatsnew_221.bug_fixes:
Expand Down
17 changes: 11 additions & 6 deletions pandas/io/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -1013,13 +1013,18 @@ def _execute_insert_multi(self, conn, keys: list[str], data_iter) -> int:

from sqlalchemy import insert

# For Oracle compliance we do not allow multi statements
dialects_not_supporting_multi = ["oracle"]

data = [dict(zip(keys, row)) for row in data_iter]
stmt = insert(self.table)
# conn.execute is used here to ensure compatibility with Oracle.
# Using stmt.values(data) would produce a multi row insert that
# isn't supported by Oracle.
# see: https://docs.sqlalchemy.org/en/20/core/dml.html#sqlalchemy.sql.expression.Insert.values
result = conn.execute(stmt, data)

if conn.dialect is not None and conn.dialect.name not in dialects_not_supporting_multi:
# For Oracle compliance we do not allow multi statements
stmt = insert(self.table).values(data)
result = conn.execute(stmt)
else:
stmt = insert(self.table)
result = conn.execute(stmt, data)
return result.rowcount

def insert_data(self) -> tuple[list[str], list[np.ndarray]]:
Expand Down