Sqlite db, несколько строк обновлений: обработка текста и чисел с плавающей запятой - PullRequest
1 голос
/ 27 июля 2010

У меня есть большая база данных SQLite со смесью текста и множеством других столбцов var1 ... var 50.Большинство из них числовые, хотя некоторые основаны на тексте.

Я пытаюсь извлечь данные из базы данных, обработать их на python и записать обратно - мне нужно сделать это для всех строк в БД.

Пока что ниже работает:

# get row using select and process
fields = (','.join(keys)) # "var1, var2, var3 ... var50"
results = ','.join([results[key] for key in keys]) # "value for var1, ... value for var50"
cur.execute('INSERT OR REPLACE INTO results (id, %s) VALUES (%s, %s);' %(fields, id, results))

Это, однако, обнуляет столбцы, которые я явно не добавляю обратно.Я могу исправить это, переписав код, но это выглядит довольно грязно, поскольку мне пришлось бы заключать в кавычки, используя конкатенацию строк, и переписывать данные, которые были там с самого начала (то есть столбцы, которые я не менял).

Видимо, способ запуска обновлений в строках выглядит примерно так:

update table set var1 = 4, var2 = 5, var3="some text" where id = 666;

Предположительно, для меня было бы возможно запустить map и как-то добавить знаки = (не уверенкак), но как бы я процитировал все результаты надлежащим образом (поскольку мне пришлось бы заключать в кавычки текстовые поля, и они могли бы также содержать кавычки внутри них ...)?

Я немного запутался.Любые указатели были бы очень полезны.

Спасибо!

Ответы [ 3 ]

3 голосов
/ 27 июля 2010

Как подчеркивали другие, используйте параметризованные аргументы. Вот пример того, как вы могли бы создать оператор SQL, когда он имеет переменное количество ключей:

sql=('UPDATE results SET '
     + ', '.join(key+' = ?' for key in keys)
     + 'WHERE id = ?')
args = [results[key] for key in keys] + [id]
cur.execute(sql,args)
1 голос
/ 27 июля 2010

Использовать параметр замена . Это более надежно (и, я думаю, безопаснее), чем форматирование строк.

Так что, если вы сделали что-то вроде

query = 'UPDATE TABLE SET ' + ', '.join(str(f) + '=?,' for f in fields) + ';'

Или альтернативно

query = 'UPDATE TABLE SET %s;' % (', '.join(str(f) + '=?,' for f in fields))

Или используя новый стиль форматирования:

query = 'UPDATE TABLE SET {0};'.format(', '.join(str(f) + '=?,' for f in fields))

Итак, вся программа будет выглядеть примерно так:

vals = {'var1': 'foo', 'var2': 3, 'var24':999}
fields = vals.keys()
results = vals.values()
query = 'UPDATE TABLE SET {0};'.format(', '.join(str(f) + '=?,' for f in fields))
conn.execute(query, results)

И это должно сработать - и я полагаю, делать то, что вы хотите.

0 голосов
/ 27 июля 2010

Вам не нужно заботиться о таких вещах, как цитаты и т. Д., И на самом деле вам это не нужно.Если вы делаете это так, это не только более удобно, но и решает проблемы безопасности, известные как инъекции SQL:

sql = "update table set var1=%s, var2=%s, var3=%s where id=666" 
cursor.execute(sql, (4, 5, "some text"))

Ключевым моментом здесь является то, что SQL и значения во втором операторе не 't разделены символом «%», но символом «,» - это не строковая манипуляция, но вместо этого вы передаете в функцию execute два аргумента: фактический sql и значения.Каждый% s заменяется значением из кортежа значений.тогда драйвер базы данных знает, как позаботиться об отдельных типах значений.

оператор вставки можно переписать таким же образом, хотя я не уверен и в настоящее время не могу проверить, можно ли таким же образом заменить имена полей (первый% s в вашем операторе insert-sql)

поэтому, чтобы вернуться к общей проблеме, вы можете циклически перебирать свои значения и динамически добавлять ", var% d = %% s"% i для i-й переменной, добавляя фактическое значение в список вв то же время

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