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

问题描述 投票:2回答:1

我创建了一个包含多个列的数据库,并希望使用存储在两个列(名为“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()
python sqlite
1个回答
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。这具有为数据中的每一行重写它的效果。

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

© www.soinside.com 2019 - 2024. All rights reserved.