0

我有一个问题,也许它在某个地方回答了,但我找不到答案。所以我得到了一个包含一张表的 Sqlite db,比如说手机型号和制造商:

Samsung
Apple
Iphone
Apple
Galaxy
Samsung
Ipod
Nexus

所以我想要实现的是制作一个脚本来替代:

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

我想要一个像字典这样的数据结构(我知道这个例子是不可能的,但只是为了说明),我可以从文件中读取来进行更新查询:

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

因此,当脚本找到任何值时,它会用键替换它

值可能很多——比如说大约 10 个,所以使用 if/or 语句将是不切实际的,而且我不会每次需要更改某些内容时都去代码并更正它——这就是为什么我想保留我的“字典”文本文件并从脚本中读取。

我将不胜感激任何指出我正确方向的想法

谢谢你。

4

3 回答 3

1

首先,您可以制作一个将替换值映射到“原始值”列表的字典:

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

您可以将其放入像 mapping.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 个。我还没有检查它的工作原理。

于 2013-05-24T13:20:41.857 回答
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"]}

Python代码:

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;
于 2013-05-24T12:33:58.797 回答
0

如果您必须一次性进行大量替换,我建议您使用包含新旧列的临时表

所以你的字典看起来像

苹果、苹果

平板电脑,苹果

Nexus,三星

银河,三星

您可以使用批量加载器将此字典上传到临时表

将数据批量加载到 sqlite 中?

然后运行一个更新命令一次性更新所有旧值

Oracle 中 SQL 的要点是

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
)
于 2013-05-24T12:36:04.863 回答