SQLAlchemy 在 Oracle DB 中批量插入 blob 数据

SQLAlchemy bulk insert blob data in Oracle DB

我正在尝试在 SQLAlchemy 中使用 Oracle DB 进行批量插入操作,它使用 blob 数据插入 60k 行。

这就是我的 table 和代码的样子:

CREATE TABLE datatables (
    id INTEGER NOT NULL, 
    table_name VARCHAR2(50 CHAR), 
    row_id VARCHAR2(50 CHAR), 
    row_data BLOB, 
    PRIMARY KEY (id)
)
with Session() as session:
    session.execute(
        DataTables.__table__.insert(),
        datas
    )

其中 DataTables 是 SQLAclhemy class 映射 table 和 datas 是这样的字典列表 {'id': 1, 'table_name': 'app', 'row_id': 'version', 'row_data': '....'}

使用这样的代码我得到了这个 sql 声明

sqlalchemy.engine.Engine INSERT INTO datatables (id, table_name, row_id, row_data) VALUES (:id, :table_name, :row_id, :row_data)
sqlalchemy.engine.Engine [generated in 0.14718s] [{'id': 1, 'table_name': 'app', 'row_id': 'version', 'row_data': b'some_data'}, ...]

它永远运行,即使在 30 分钟后它还没有完成。当我启用 DPI 跟踪时,有很多这样的行:

ODPI [12912] 2021-12-18 00:07:36.019: ref 0000019C3D15C5B0 (dpiConn) -> 8
ODPI [12912] 2021-12-18 00:07:36.020: ref 0000019C413F0C20 (dpiLob) -> 1 [NEW]
ODPI [12912] 2021-12-18 00:07:36.020: ref 0000019C3D15C5B0 (dpiConn) -> 9
ODPI [12912] 2021-12-18 00:07:36.020: ref 0000019C413F1990 (dpiLob) -> 1 [NEW]

但是如果我使用原始 sql:

session.execute('insert into DATATABLES (id, table_name, row_id, row_data) values (:id, :table_name, :row_id, :row_data)', datas)

DPI 跟踪更改为:

ODPI [00796] 2021-12-18 00:14:55.246: ref 000002486741EAF0 (dpiVar) -> 0
ODPI [00796] 2021-12-18 00:14:55.246: ref 00000248617D2DF0 (dpiConn) -> 6
ODPI [00796] 2021-12-18 00:14:55.246: fn end dpiVar_release(000002486741EAF0) -> 0
ODPI [00796] 2021-12-18 00:14:55.246: fn start dpiVar_setFromBytes(000002486741EBB0)
ODPI [00796] 2021-12-18 00:14:55.247: fn end dpiVar_setFromBytes(000002486741EBB0) -> 0
ODPI [00796] 2021-12-18 00:14:55.247: fn start dpiVar_setFromBytes(0000024864E5FDE0)
ODPI [00796] 2021-12-18 00:14:55.247: fn end dpiVar_setFromBytes(0000024864E5FDE0) -> 0
ODPI [00796] 2021-12-18 00:14:55.247: fn start dpiVar_setFromBytes(0000024864E601A0)
ODPI [00796] 2021-12-18 00:14:55.247: fn end dpiVar_setFromBytes(0000024864E601A0) -> 0

批量插入在 15 秒内完成。

SQL 两种情况下的语句相同。为什么它的工作方式不同?当然,我可以使用原始 sql,但我想使用 DataTables.__table__.insert(),因为如果 table 或列名称会更改 - 我不需要为此修复 sql每次。

最好将此类问题报告为 SQLAlchemy 中的错误,您可以在以下位置进行报告:https://github.com/sqlalchemy/sqlalchemy/issues/ 否则我们完全不知道这个问题。

在这种情况下,我们已收到此问题的警报,并将寻求根据 cx_oracle 开发人员为 SQLAlchemy 2.0 更新我们的 LOB 设置,在 https://github.com/sqlalchemy/sqlalchemy/issues/7494

进行跟踪