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

2024-03-29 10:40:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经创建了一个包含多个列的数据库,并希望使用其中两个列(名为“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()

Tags: keyvalueprconnlistrowkwhcost
1条回答
网友
1楼 · 发布于 2024-03-29 10:40:06

不知道为什么不起作用。你试过用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循环之前创建列表,然后为每一行追加列表。在

^{pr2}$

第二种方法是在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 list已经正确创建,那么将(dol_pr_kW[1],dol_pr_kW[0])传递给executemany将传递列表中的前两行,而不是将(key,value)反转为(value,key)。您需要做一个列表理解来在一行代码中完成交换。我只是将它作为一个单独的行来处理,并将其分配给变量data_to_insert以提高可读性。在

相关问题 更多 >