python - cx_Oracle 更新表时执行/executemany 错误
问题描述
我需要从我的 Python 代码有条件地更新 Oracle 表。这是一段简单的代码,但我遇到了cx_Oracle.DatabaseError: ORA-01036: invalid variable name/number并尝试了以下尝试
id_as_list = ['id-1', 'id-2'] # list of row IDs in the DB table
id_as_list_of_tuples = [('id-1'), ('id-2')] # the same as list of tuples
sql_update = "update my_table set processed = 1 where object_id = :1"
# then when I tried any of following commands, result was "illegal variable name/number"
cursor.executemany(sql_update, id_as_list) # -> ends with error
cursor.executemany(sql_update, id_as_list_of_tuples) # -> ends with error
for id in id_as_list:
cursor.execute(sql_update, id) # -> ends with error
正确的解决方案是在 SQL 语句中使用字典列表和键名:
id_as_list_of_dicts = [{'id': 'id-1'}, {'id': 'id-2'}]
sql_update = "update my_table set processed = 1 where object_id = :id"
cursor.executemany(sql_update, id_as_list_of_dicts) # -> works
for id in id_as_list_of_dicts:
cursor.execute(sql_update, id) # -> also works
我找到了一些类似的帮助和教程,它们都使用“:1,:2,...”语法(但另一方面,我没有找到任何带有更新和 cx_Oracle 的示例)。虽然我的问题已经在字典的帮助下解决了,但我想知道这是否是常见的更新方式,或者我是否在 ":1, :2,..." 语法中做错了什么。
Oracle 12c、Python 3.7、cx_Oracle 7.2.1
解决方案
您确实可以绑定字典,但创建字典的开销可能是不可取的。您需要确保在使用executemany()
. 所以在你的情况下,你想要这样的东西:
id_as_list = [['id-1'], ['id-2']] # list of row IDs in the DB table
id_as_list_of_tuples = [('id-1',), ('id-2',)] # the same as list of tuples
在第一个实例中,您有一个字符串列表。字符串本身就是序列,因此在这种情况下 cx_Oracle 需要 4 个绑定变量(每个字符串中的字符数)。
在第二个实例中,您拥有与第一个实例相同的数据——因为您只是在字符串周围包含括号,而不是创建元组!您需要如我的示例中所示的尾随逗号来创建您认为正在创建的元组!
推荐阅读
- c# - ASP.NET 和 Visual Studio 2019:如果 Web.config 中有 configSource,如何设置 Web.Debug 和 Web.Release?
- video-streaming - 有没有办法使用 VLC 从网络摄像头流式传输原始 YUY2?(错误:无法创建分包器输出(YUY2))
- shell - Elasticsearch curl 帖子在 CI 作业中挂起并超时
- azure - 包含超过一百万个文件的 AzCopy V10 下载目录
- android - 如何使用 Xamarin 表单通过 VPN 访问 API?
- python - 大摇大摆,然后烧瓶或相反
- python - 如何检查翻译是否由社区使用 Python 中的 googletrans 模块检查?
- c# - 谓词如何与 ListCollectionView 一起使用
- php - Trying to sort by price but not working in WordPress
- ruby-on-rails - 添加 pg_dump 后运行 rails 服务器时 main:Object (NoMethodError) 的未定义方法“命名空间”