我使用与Python接口的SQLite(sqlite3)来保存用于处理大量数据的表中的参数。假设我最初已经填充了表,但随后更改了参数,我想更新我的表。如果我创建一个包含更新参数的Python列表,对于表中的每一行和每列,如何更新表?
我看过here和here(虽然后者指的是C ++而不是Python)但这些并没有真正回答我的问题。
为了具体说明,我在下面展示了一些代码:
import sqlite3 as sql
import numpy as np
db = sql.connect('./db.sq3')
cur = db.cursor()
#... Irrelevant Processing Code ...#
cur.execute("""CREATE TABLE IF NOT EXISTS process_parameters (
parameter_id INTEGER PRIMARY KEY,
exciton_bind_energy REAL,
exciton_bohr_radius REAL,
exciton_mass REAL,
exciton_density_per_QW REAL,
box_trap_side_length REAL,
electron_hole_overlap REAL,
dipole_matrix_element REAL,
k_cutoff REAL)""")
#Parameter list
process_params = [(E_X/1.6e-19, a_B/1e-9, m_exc/9.11e-31, 1./(np.sqrt(rho_0)*a_B), D/1e-6, phi0/1e8, d/1e-28, k_cut/(1./a_B)) for i in range(0,14641)]
#Check to see if table is populated or not
count = cur.execute("""SELECT COUNT (*) FROM process_parameters""").fetchone()[0]
#If it's not, fill it up
if count == 0:
cur.executemany("""INSERT INTO process_parameters VALUES(NULL, ?, ?, ?, ?, ?, ?, ?, ?);""", process_params)
db.commit()
现在,假设在后续处理运行中,我更改了process_params
中的一个或多个参数。我想要的是在Python将使用最新版本的参数更新数据库的任何后续运行中。所以我做了
else:
cur.executemany("""UPDATE process_parameters SET exciton_bind_energy=?, exciton_bohr_radius=?, exciton_mass=?, exciton_density_per_QW=?, box_trap_side_length=?, electron_hole_overlap=?, dipole_matrix_element=?, k_cutoff=?;""", process_params)
db.commit()
db.close()
但是当我这样做时,脚本似乎挂起(或者进展得很慢),这样Ctrl + C甚至不会退出脚本(通过ipython
运行)。
我知道在这种情况下,使用庞大的Python列表进行更新可能无关紧要,但这是我想澄清的原则,因为在另一个时间,我可能不会更新具有相同值的每一行。如果有人能帮我理解正在发生的事情和/或如何解决这个问题,我真的很感激。感谢信。
答案 0 :(得分:2)
cur.executemany("""
UPDATE process_parameters SET
exciton_bind_energy=?,
exciton_bohr_radius=?,
exciton_mass=?,
exciton_density_per_QW=?,
box_trap_side_length=?,
electron_hole_overlap=?,
dipole_matrix_element=?,
k_cutoff=?
;
""", process_params)
您在更新时忘记了WHERE子句。如果没有WHERE子句,UPDATE语句将更新表中的每个行。由于您提供了14641组参数,因此SQLite驱动程序将更新14641(输入)×14641(表中的行)= 2.14亿次的行,这表明它的速度很慢。
正确的方法是每次只更新相关行:
cur.executemany("""
UPDATE process_parameters SET
exciton_bind_energy=?,
exciton_bohr_radius=?,
exciton_mass=?,
exciton_density_per_QW=?,
box_trap_side_length=?,
electron_hole_overlap=?,
dipole_matrix_element=?,
k_cutoff=?
WHERE parameter_id=?
-- ^~~~~~~~~~~~~~~~~~~~ don't forget this
;
""", process_params)
当然,这意味着process_params
必须包含参数ID,您还需要修改INSERT语句以插入参数ID。