使用 cx_Oracle 中 csv 文件中的变量更新数据库
Posted
技术标签:
【中文标题】使用 cx_Oracle 中 csv 文件中的变量更新数据库【英文标题】:Update database using variable from csv file in cx_Oracle 【发布时间】:2021-05-30 22:08:02 【问题描述】:在使用 cx_Oracle 和 Python3.6.8 在 Oracle 数据库中执行更新命令时遇到错误ORA-01036:非法变量名称/编号。
我想使用 CSV 文件 (db_results.csv) 中的变量值并执行更新命令。
db_results.csv 文件如下所示:
id, order_id, product, Courier, state
01, ORD987, Keyboard, DHL, TX
02, ORD976, Charger, Blue Dart, NY
我的代码:
con = cx_Oracle.connect("abc/abc@abc")
cur = con.cursor()
with open(r'D:\db_results.csv') as file:
next(file)
for line in file:
x = line.replace('\n', ' ').replace('\r', '')
columns = x.split(",")
y = columns[1]
SQL = "update inventory set model='301547' where order_id = '?'"
cur.execute(SQL, y)
con.commit()
con.close()
在 cx_Oracle 中使用 UPDATE 是否有任何特定语法?试图找到这方面的例子,但目前还没有找到。
【问题讨论】:
供未来读者参考,cx_Oracle 文档位于cx-oracle.readthedocs.org/en/latest/index.html,在github.com/oracle/python-cx_Oracle/tree/master/samples 有示例 【参考方案1】:ORA-01036 由于 oracle 的占位符类型错误而引发,而更喜欢使用以冒号开头的整数,例如
:1
, :2
不要忘记修剪第二个占位符的值以获得
去掉 y
值周围的空格
无需在 DML 中嵌入参数,而是对其进行转换
到一个元组,例如(301547, y)
...
with open(r'D:\db_results.csv') as file:
next(file)
for line in file:
x = line.replace('\n', ' ').replace('\r', '')
columns = x.split(",")
y = columns[1]
SQL = "UPDATE inventory SET model=:1 WHERE order_id = TRIM(:2)"
cur.execute(SQL, (301657, y))
con.commit()
con.close()
【讨论】:
嗨,Barbaros,我尝试使用以下代码,但出现错误。 cur.executemany(SQL, (301547, y)) TypeError: parameters 应该是序列/字典列表或指定语句执行次数的整数 对不起@GauravMarothia,我不小心把很多留在了那里,请按编辑后重试。 成功了...非常感谢@Barbaros Özhan 嗨,Barbaros,代码运行没有任何错误,但数据库中的值仍未更新。你能帮忙吗? @GauravMarothia 您是否像在原始代码中一样在 DML 之后添加con.commit()
?您确定表中存在匹配的order_id
值吗?【参考方案2】:
为每个 CSV 行调用一次 cur.execute()
(如已接受的答案所示)会非常慢,不推荐。
相反,看看使用cur.executemany()
,类似于cx_Oracle文档Loading CSV Files into Oracle Database中的代码:
with open('testsp.csv', 'r') as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
sql = "insert into test (id,name) values (:1, :2)"
data = []
for line in csv_reader:
data.append((line[0], line[1]))
if len(data) % batch_size == 0:
cursor.executemany(sql, data)
data = []
if data:
cursor.executemany(sql, data)
con.commit()
在您的情况下,SQL 将是 UPDATE 语句,您只需要使用您想要的值构造 data
变量。
【讨论】:
以上是关于使用 cx_Oracle 中 csv 文件中的变量更新数据库的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 cx_Oracle 在 Python 中返回 SQLPLUS 变量
Python应用实战系列-如何通过Python来操作Oracle数据库:cx_Oracle