繁体   English   中英

Python,SQlite和字符串替换

[英]Python, SQlite and string substitution

我有一个问题,也许它在某个地方回答了,但我找不到答案。 因此,我得到了一个包含一个表组成的Sqlite数据库,比方说电话型号和制造商:

Samsung
Apple
Iphone
Apple
Galaxy
Samsung
Ipod
Nexus

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

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

我想拥有一个像字典这样的数据结构(我知道该示例是不可能的,但仅用于说明),我可以从文件中读取该数据结构以进行UPDATE查询:

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

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

值可以是很多-假设大约10,所以使用if / or语句将是不切实际的,而且我不需要每次都需要对代码进行一些更改并对其进行更正-因此,这就是为什么我想保留我的“字典”文本文件并从脚本中读取。

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

谢谢。

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

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个变量。我还没有检查它到底能工作多少。

当心:以下不安全的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;

如果您必须一口气做很多替换,我建议您使用包含旧列和新列的临时表

所以你的字典看起来像

苹果手机

苹果iPad

Nexus,三星

三星Galaxy

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

将数据批量加载到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
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM