如果发生任何错误,回滚 pandas to_sql() 操作

Rollback a pandas to_sql() operation if any error occurs

如果发生任何错误,我想回滚 df.to_sql,但我找不到 to_sql-errors 继承自的基本异常。

sqlalchemy 开始,它的所有错误都继承自 sqlalchemy.exc.SQLAlchemyError,但我不知道 SQLAlchemyError 是否继承自 BaseExceptionException 或其他。

如果我抓到 SQLAlchemyErrorException 我会假设我是安全的?

import pandas as pd
from sqlalchemy import create_engine
from sqlalchemy.exc import SQLAlchemyError

df = pd.read_csv("data.csv")

engine = create_engine()

with engine.connect() as conn:
    tran = conn.begin()
    
    try:
      df.to_sql("table", conn, index=False, if_exists="append")

      
    except: (SQLAlchemyError,Exception): #Want to capture all errors
      tran.rollback()
      print("Shiat broke down ...")

您只需点击几下就可以查看源代码 SQLAlchemyError

您可以使用with engine.begin()(而不是with engine.connect())为您处理交易。如果发生错误,该块将自动回滚,否则将提交。

比如这段代码

import pandas as pd
import sqlalchemy as sa

connection_url = (
    "mssql+pyodbc://scott:tiger^5HHH@192.168.0.199/test"
    "?driver=ODBC+Driver+17+for+SQL+Server"
)
engine = sa.create_engine(
    connection_url,
    echo=True,
)
cause_error = False

table_name = "thing"
with engine.begin() as conn:
    conn.exec_driver_sql(f"DROP TABLE IF EXISTS {table_name}")
    conn.exec_driver_sql(
        f"CREATE TABLE {table_name} (id int primary key, txt varchar(50))"
    )
    if cause_error:
        conn.exec_driver_sql(
            f"INSERT INTO {table_name} (id, txt) VALUES (1, 'xyz')"
        )

df = pd.DataFrame([(1, "foo"), (2, "bar")], columns=["id", "txt"])
try:
    with engine.begin() as conn:
        df.to_sql(table_name, conn, if_exists="append", index=False)
        print(">>> All good.")
except Exception as e:
    print(">>> Something went wrong!")

在日志中显示此内容

2022-02-01 10:45:01,835 INFO sqlalchemy.engine.Engine INSERT INTO thing (id, txt) VALUES (?, ?)
2022-02-01 10:45:01,835 INFO sqlalchemy.engine.Engine [generated in 0.00053s] ((1, 'foo'), (2, 'bar'))
>>> All good.
2022-02-01 10:45:01,860 INFO sqlalchemy.engine.Engine COMMIT

但是,如果我们使用 cause_error = True 那么日志包含

2022-02-01 10:53:29,385 INFO sqlalchemy.engine.Engine INSERT INTO thing (id, txt) VALUES (?, ?)
2022-02-01 10:53:29,385 INFO sqlalchemy.engine.Engine [generated in 0.00046s] ((1, 'foo'), (2, 'bar'))
2022-02-01 10:53:29,423 INFO sqlalchemy.engine.Engine ROLLBACK
>>> Something went wrong!