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

时间:2018-09-06 19:11:40

标签: python sqlite

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

问题:数据库中的新列未使用新数据进行更新,我不确定为什么。新列中的值显示为“ NULL”

感谢您的帮助。这是我的代码:

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()

1 个答案:

答案 0 :(得分:2)

不知道为什么它不起作用。您是否尝试过仅用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中执行此操作,请测试该方法是否有效,至少可以为您提供一些有关当前代码出了什么问题的提示。

更新:我现在又遇到了一些问题。 首先,我看到您在for循环之前创建了一个空字典dol_pr_kW。不必这样做,因为以后无论如何将其重新定义为列表。

然后,您尝试在for循环中创建列表dol_pr_kW。这样会覆盖数据中的每一行。

我将给出几种解决方法。看起来您一次尝试了一些不同的事情(使用dict和list,构建两个列表并压缩到第三个列表等),这增加了您的麻烦,因此,我正在简化代码以使其更易于理解。在每个解决方案中,我将创建一个名为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])传递给execute会传递列表中的前两行,而不是将(key,value)反转为(value,键)。您需要执行列表理解才能在一行代码中完成交换。我只是将其作为单独的一行进行了处理,并将其分配给变量data_to_insert以提高可读性。