Использование двух столбцов в существующей базе данных SQLite для создания третьего столбца с использованием Python - PullRequest
0 голосов
/ 06 сентября 2018

Я создал базу данных с несколькими столбцами и хочу использовать данные, хранящиеся в двух столбцах (с именами «стоимость» и «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 голосов
/ 06 сентября 2018

Не уверен, почему это не работает. Вы пытались просто делать все это в 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, проверка того, работает ли это, по крайней мере, даст вам несколько советов о том, что не так с вашим текущим кодом.

Обновление : я вижу еще несколько проблем. Сначала я вижу, что вы создаете пустой словарь dol_pr_kW перед циклом for. В этом нет необходимости, так как вы все равно определяете его как список позже.

Затем вы пытаетесь создать список dol_pr_kW внутри цикла for. Это приводит к перезаписи его для каждой строки в данных.

Я дам несколько разных способов ее решения. Похоже, что вы пробовали несколько разных вещей одновременно (используя 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 передала бы первые две строки в списке вместо обращения (ключ, значение) к (значение, ключ). Вы должны сделать понимание списка, чтобы выполнить обмен в одной строке кода. Я просто сделал это отдельной строкой и назначил переменную data_to_insert для удобства чтения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...