2013-05-24 2 views
0

У меня вопрос, возможно, он ответил где-то, но я не могу найти ответ. Таким образом я получил БД SQLite с одной таблицей состоят, скажем моделей телефонов и производителей:Python, SQlite и замена строк

Samsung 
Apple 
Iphone 
Apple 
Galaxy 
Samsung 
Ipod 
Nexus 

так, что я пытаюсь достичь, это сделать скрипт для замены:

Iphone or Ipod -> Apple 
Galaxy or Nexus -> Samsung 

Я хотел бы имеет структуру данных, как словарь (я знаю, что пример невозможно, но только для иллюстрации), что я могу читать из файла, чтобы сделать UPDATE запрос:

{ 
'Apple':'Iphone','Ipod' 
'Samsung':'Galaxy','Nexus'} 

так Whe n скрипт найдет любое из значений, которое оно заменит ключом

значений может быть довольно много - допустим около 10, поэтому использование if/или операторов будет непрактичным, и я не каждый раз, когда мне нужно что-то менять, переходите к коду и исправьте его, поэтому я хочу сохранить свой «словарь» в текстовом файле и прочитать его из скрипта.

я буду иметь в виду, за любые идеи, которые указывают меня в правильном направлении

спасибо.

ответ

1

Во-первых, вы можете сделать Dict, который отображает значения замены в списках 'исходных значений':

replacements = { 
    'Apple':['Iphone','Ipod'], 
    'Samsung':['Galaxy','Nexus'] 
} 

Вы можете просто поместить это в файл, например map.py, и сделать from mapping import replacements. JSON также будет разумным форматом сериализации. После того, как вы получите словарь, вы можете выполнять итерацию по всем полям, сгенерировать параметризованный запрос, соответствующий длине строк для замены.

for replacement, replacables in replacements.iteritems(): 
    query = 'update foo set value=? where value in ({})'.format(",".join("?"*len(replacables))) 
    c.execute(query, [replacement]+replacables) 

Таким образом, вы не получаете инъекций SQL. Когда я попытался, он работал до 100 переменных, не с 1000. Я не проверял, насколько это точно работает.

+0

+1 для избежания SQL-инъекции. –

0

Остерегайтесь: Неверное повторное использование SQL-инъекции!

База данных перед:

$ sqlite3 foo.db .dump 
PRAGMA foreign_keys=OFF; 
BEGIN TRANSACTION; 
CREATE TABLE t (f varchar); 
INSERT INTO "t" VALUES('foo'); 
INSERT INTO "t" VALUES('bar'); 
INSERT INTO "t" VALUES('baz'); 
COMMIT; 

JSON файл для отображения:

{"B": ["bar", "baz"], "F": ["foo"]} 

Питон Код:

import json 
import sqlite3 

d = json.loads("d.json") 

con = sqlite3.connect("foo.db") 
cur = con.cursor() 

# Loop over the keys in d. 
for k in d: 
    # Build the SQL clause that matches all recordss for d[k]. 
    clause = " or ".join(" f = '{}' ".format(v) for v in d[k]) 
    # The SQL for the update. 
    sql = "update t set f = '{}' where {}".format(k, clause)  
    cur.execute(sql) 

con.commit()   

База данных после того, как:

$ sqlite3 foo.db .dump 
PRAGMA foreign_keys=OFF; 
BEGIN TRANSACTION; 
CREATE TABLE t (f varchar); 
INSERT INTO "t" VALUES('F'); 
INSERT INTO "t" VALUES('B'); 
INSERT INTO "t" VALUES('B'); 
COMMIT; 
0

Если вам нужно сделать много замены на одном дыхании я бы предложил использовать временную таблицу с колоннами старого и нового

так, чтобы ваш словарь будет выглядеть

Iphone, Apple

Ipad , Apple

Nexus, Samsung

Galaxy, Samsung

Вы ча п загрузить этот словарь в временную таблицу с помощью массовой загрузки

Bulk load data into sqlite?

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

Суть SQL в Oracle будет

update yourtable 
set yourtable.phone = (select temp.new 
from yourtable , temp 
where 
temp.old = yourtable.phone) 
where exists 
(
select 1 from yourtable , temp 
where 
temp.old = yourtable.phone 
) 
+0

Это не отвечает на конкретный вопрос. Кроме того, 10 - это не «много». –

+0

Да .. он сказал любую идею, которая указывает ему в правильном направлении .. – sethi

+0

SQLite! = Oracle. Вы знаете Python или SQLite? –

Смежные вопросы