python - 如何从Oracle表中删除大量没有主键的记录

标签 python pandas cx-oracle

情况:我正在将整个 SQL 表加载到我的程序中。为了方便起见,我使用 pandas 来维护行数据。然后,我创建一个数据框,其中包含我想要从 SQL 表中删除的行。不幸的是(并且我无法更改这一点)除了内置 Oracle ROWID(这不是真正的表列,它是伪列)之外,该表没有任何主键,但我可以如果需要的话,使 ROWID 成为我的数据帧的一部分。

该表有数十万行,每次运行程序时我可能会删除几千条记录。

问题: 使用 Cx_Oracle 删除没有主键的多行/记录的最佳方法是什么? 我不认为创建一个循环来提交数千条删除语句是非常有效的或Pythonic的。尽管我担心构建一个与 ROWID 无关的单一 SQL 删除语句,并且该语句包含一个包含数千个项目的子句:

Where ROWID IN ('eg1','eg2',........, 'eg2345')

这种担忧是否有效?有什么建议吗?

最佳答案

使用 ROWID

由于您可以使用ROWID,因此这将是理想的方法。根据 Oracle 版本的不同,对于 IN 子句中包含这么多元素的查询来说,查询长度限制可能足够大。问题是 IN 表达式列表中的元素数量 - limited to 1000 .

因此,您要么必须一次将 RowID 列表分成 1000 个集合,要么一次只删除一行;有或没有 executemany()

>>> len(delrows)  # rowids to delete
5000
>>> q = 'DELETE FROM sometable WHERE ROWID IN (' + ', '.join(f"'{row}'" for row in delrows) + ')'
>>> len(q)  # length of the query
55037
>>> # let's try with just the first 1000 id's and no extra spaces
... q = 'DELETE FROM sometable WHERE ROWID IN (' + ','.join(f"'{row}'" for row in delrows[:1000]) + ')'
>>> len(q)
10038

您可能在查询长度限制内,甚至可以使用最小的 ',' 项目分隔符保存一些字符。

没有 ROWID

如果没有主键或 ROWID,识别每一行的唯一方法是在 WHERE 子句中指定所有列,并且一次执行多行操作,需要将它们进行“或”运算:

DELETE FROM sometable
WHERE  ( col1 = 'val1'
         AND col2 = 'val2'
         AND col3 = 'val3' )  -- row 1
    OR ( col1 = 'other2'
         AND col2 = 'value2'
         AND col3 = 'val3' )  -- row 2
    OR ( ... )                -- etc

如您所见,这不是构造最好的查询,但允许您在没有 ROWID 的情况下完成此操作。

<小时/>

在这两种情况下,您可能不需要使用参数化查询,因为 1 中的 IN 列表或 2 中的 OR 分组是可变的。 (是的,您可以在构建具有数千个参数的整个扩展 SQL 后创建参数化的它。不确定它的限制是什么。)executemany() 方法绝对更容易编写和执行,但是对于速度,单个大型查询(以上两个中的任何一个)可能会优于具有数千个项目的executemany。

关于python - 如何从Oracle表中删除大量没有主键的记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54794543/

相关文章:

Python str.find() 覆盖 Element.find(),如何规避?

python - 进行 train_step.run() 时出现 Tensorflow 错误

python - 从 `which` 获取返回值来测试目录是否存在

python - 将 pandas 表导入 tkinter 项目

python - 尝试导入 python 的 cx_Oracle 问题

python - Numpy 从多维数组中删除一行

python - 如何使用多索引移动 Pandas DataFrame?

python - 将长表转换为宽表并根据行创建列

python - 如何将 cx_oracle 与 Pyinstaller 捆绑在一起

python-3.x - 带有故障转移 oracle url 的 Python cx_Oracle 连接