使用现有SQLite数据库中的两列,使用Python创建第三列
我已经创建了一个包含多列的数据库,我希望使用其中两列(名为“cost”和“Mwe”)中存储的数据创建一个新列“Dollar_per_KWh”。我创建了两个列表,一个包含rowid,另一个包含我要填充新的Dollar_per_KWh列的新值。当它遍历所有行时,这两个列表被压缩到一个包含元组的字典中。然后我尝试填充新的sqlite列。代码运行,我没有收到任何错误。当我把字典打印出来时,它看起来是正确的 问题:我的数据库中的新列没有用新数据更新,我不知道为什么。新列中的值显示为“NULL” 谢谢你的帮助。这是我的密码:使用现有SQLite数据库中的两列,使用Python创建第三列,python,sqlite,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()
不知道为什么它不起作用。您是否尝试过用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])传递给executemany将传递列表中的前两行,而不是将(键,值)反转为(值,键)。您需要进行列表理解,才能在一行代码中完成交换。我只是将其作为一个单独的行,并将其分配给变量数据\u to \u insert,以确保可读性。
**
是sqlite中的一个语法错误。他需要添加一个用户定义的求幂函数。(当然,也可以在数字中使用大量的零)但要解决这个问题,而且,是的,用这种方法更容易做到。谢谢!我没有意识到**在SQLite中给出了一个错误。我只是将其简化为(cost/MWE)*1000。在尝试此操作时,我查看了数据库的模式,发现“cost”被设置为“TEXT”,而不是“INTEGER”。我纠正了这一点,并在SQLite的db浏览器中尝试了上述方法,效果良好。当我在一个新的python代码中尝试它时,它没有产生任何错误,但没有填充Dollar_per_KWh列。因为它可以在SQL中完成所有工作,但不能在python中完成,所以您建议我接下来研究什么?我用一些应该在python中工作的解决方案更新了我的答案。直到我再看一遍,我才注意到这个问题。什么是dol\u pr\u kW[0]
和dol\u pr\u kW[1]
?我怀疑它们不是你想象的那样(如果它们是,你只会更新一行…@Shawn它们是键、值对。dol_pr_kW[0]是rowid,dol_pr_kW[1]是新值。当我把它打印出来时,我得到了如下结果:[(1616),(2804),(3880),…,(32351)]。这些是我期望的值。你从print(dol_pr_kW[0])中得到了所有这些值吗?