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
进行跟踪
我正在尝试在 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
进行跟踪