使用现有 SQLite 数据库中的两列使用 Python 创建第三列



我创建了一个包含多列的数据库,并希望使用存储在其中两列(名为"cost"和"Mwe"(中的数据来创建新列"Dollar_per_KWh"。我创建了两个列表,一个包含rowid,另一个包含我要填充新Dollar_per_KWh列的新值。当它遍历所有行时,这两个列表被压缩到一个包含元组的字典中。然后,我尝试填充新的 sqlite 列。代码运行,我没有收到任何错误。当我打印出字典时,它看起来是正确的。

问题:我的数据库中的新列未使用新数据进行更新,我不确定原因。新列中的值显示"空">

谢谢你的帮助。这是我的代码:

conn = sqlite3.connect('nuclear_builds.sqlite')
cur = conn.cursor()
cur.execute('''ALTER TABLE Construction
ADD COLUMN Dollar_per_KWh INTEGER''')
cur.execute('SELECT _rowid_, cost, Mwe FROM Construction')
data = cur.fetchall()
dol_pr_kW = dict()
key = list()
value = list()
for row in data:
id = row[0]
cost = row[1]
MWe = row[2]
value.append(int((cost*10**6)/(MWe*10**3)))
key.append(id)
dol_pr_kW = list(zip(key, value))
cur.executemany('''UPDATE Construction SET Dollar_per_KWh = ? WHERE _rowid_ = ?''', (dol_pr_kW[1], dol_pr_kW[0]))
conn.commit()

不知道为什么它不起作用。您是否尝试过在SQL中完成所有操作?

conn = sqlite3.connect('nuclear_builds.sqlite')
cur = conn.cursor()
cur.execute('''ALTER TABLE Construction
ADD COLUMN Dollar_per_KWh INTEGER;''')
cur.execute('''UPDATE Construction SET Dollar_per_KWh = cast((cost/MWe)*1000 as integer);''')

在SQL中进行计算比将数据拉取到Python,操作它并将其推送回数据库要简单得多。

如果你出于某种原因需要在Python中执行此操作,测试这是否有效至少会给你一些提示,说明你当前的代码出了什么问题。

更新:我现在看到更多问题。 首先,我看到您正在创建一个空字典dol_pr_kW在 for 循环之前。这不是必需的,因为您稍后会将其重新定义为列表。

然后,您尝试在 for 循环中创建列表dol_pr_kW。这具有为数据中的每一行覆盖它的效果。

我将给出几种不同的解决方法。看起来您同时尝试了几种不同的事情(使用 dict 和列表,构建两个列表并压缩到第三个列表等(,这增加了您的麻烦,所以我正在简化代码以使其更易于理解。在每个解决方案中,我将创建一个名为data_to_insert的列表。这就是您将在末尾传递给 executemany 函数的内容。

第一个选项是在 for 循环之前创建列表,然后为每一行附加它。

dol_pr_kW = list()
for row in data:
id = row[0]
cost = row[1]
MWe = row[2]
val = int((cost*10**6)/(MWe*10**3))
dol_pr_kW.append(id,val)
#you can do this or instead change above step to dol_pr_kW.append(val,id).
data_to_insert = [(r[1],r[0]) for r in dol_pr_kW]

第二种方法是在 for 循环之后压缩键和值列表。

key = list()
value = list()
for row in data:
id = row[0]
cost = row[1]
MWe = row[2]
value.append(int((cost*10**6)/(MWe*10**3)))
key.append(id)
dol_pr_kW = list(zip(key,value))
#you can do this or instead change above step to dol_pr_kW=list(zip(value,key))
data_to_insert = [(r[1],r[0]) for r in dol_pr_kW]

第三,如果你宁愿把它作为一个实际的字典,你可以这样做。

dol_pr_kW = dict()
for row in data:
id = row[0]
cost = row[1]
MWe = row[2]
val = int((cost*10**6)/(MWe*10**3))
dol_pr_kW[id] = val
# convert to list 
data_to_insert = [(dol_pr_kW[id], id) for id in dol_per_kW]

然后执行调用

cur.executemany('''UPDATE Construction SET Dollar_per_KWh = ? WHERE _rowid_ = ?''', data_to_insert)
cur.commit()

我更喜欢第一种选择,因为它对我来说最容易一目了然地了解正在发生的事情。for 循环的每次迭代只是在列表末尾添加一个(id,val(。独立构建两个列表并将它们压缩在一起以获得第三个列表会更麻烦一些。

另请注意,如果正确创建了dol_pr_kW列表,将 (dol_pr_kW[1],dol_pr_kW[0]( 传递给 executemany 将传递列表中的前两行,而不是将 (key,value( 反转为 (value,key(。您需要执行列表理解才能在一行代码中完成交换。我只是将其作为单独的行执行此操作,并将其分配给变量data_to_insert以提高可读性。

最新更新