【问题标题】:Update Firebird table with data from csv Python使用来自 csv Python 的数据更新 Firebird 表
【发布时间】:2021-03-18 08:19:02
【问题描述】:

假设我们有一个包含如下付款信息的 CSV 文件:

somthing1:500.00
somthing2:300.00
somthing3:200.00

我需要更新 Firebird 数据库中 tableB 中的不同行,该数据库有一个名为 paid 的列,其值位于 CSV 文件的第二列中。出于这个原因,我创建了一个全局临时表,只是为了将数据泵入其中,然后更新所需的表。我尝试的是这样的:

idd = 0
with open('file.csv', 'r', encoding='utf-8', newline='') as file:
    reader = list(csv.reader(file, delimiter=':'))
    for row in reader:
        idd += 1
            c.execute("""INSERT INTO temp_table (id,code,paid) VALUES (?,?,?)""", 
            (idd,str(row[0]),str(row[1]), ))

这按预期工作 - 表格已填充。之后我尝试像这样更新其他表:

c.execute("""select paid from temp_table;""")
res = c.fetchall()
for r in res:
    c.execute(f"""UPDATE tableB SET paid = {r[0]} WHERE oid = 10;""")

这确实有效 - 对于来自 SELECT 查询的每个结果,它都会使用与该查询的下一个结果相同的值更新所有行。我尝试在数据库本身中使用 MERGE 得到相同的结果 - 每一行都使用来自 temp_table 的相同值进行更新:

MERGE INTO tableB b
USING (SELECT paid FROM temp_table) e
ON b.paid = 0 AND oid = 10
WHEN MATCHED THEN
UPDATE SET b.paid = e.paid;

我需要一些方法来更新来自tableB 的第一行与来自 CSV 的第一行等等。我错过了什么?

【问题讨论】:

    标签: python sql csv firebird


    【解决方案1】:

    问题是您没有将temp_table 中的行与tableB 中的行相关联。

    在您的初始尝试中,您将tableB 中的所有行更新为oid = 10。同样,在您的第二次尝试中,您使用paid = 0 更新所有行,而不与temp_table 关联。

    您需要添加一个条件来匹配表之间的行,假设两者都有一个id 列:

    MERGE INTO tableB b
    USING (SELECT paid FROM temp_table) e
    ON b.paid = 0 AND b.oid = 10 AND b.id = e.id
    WHEN MATCHED THEN
      UPDATE SET b.paid = e.paid;
    

    【讨论】:

    • 如果 id 列不相等,例如b.id = 10 , e.id = 5,这会起作用吗?
    • @T0ny1234 对于tableB1 中的每一行,必须有一种方法将tableB 中的那一行关联到temp_table 中的最多一行(Firebird 实际上允许您匹配单行到多行,因此可能会更新多次,但这应该被认为是一个错误)。无论是通过 ID(这只是我的示例)还是完全不同的条件,我无法知道,因为您没有在问题中提供足够的信息来做出决定。
    • 再次感谢您。你所说的正是我所担心的这一切背后的原因。为了获得所需的信息,我必须在 SELECT 条件下创建一个 JOIN 和另一个表。
    • @T0ny1234 添加连接应该很简单,对吧?
    • 是的。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-19
    • 1970-01-01
    • 2020-06-29
    • 1970-01-01
    • 2018-06-12
    相关资源
    最近更新 更多