在Python中将JSON转换为SQLite – 如何正确地将json键映射到数据库列?
我想将我创build的JSON文件转换为SQLite数据库。
我的意图是稍后决定哪个数据容器和入口点是最好的,json(通过文本编辑器的数据input)或SQLite(通过像SQLiteStudio这样的类似电子表格的GUI的数据input)。
我的json文件是这样的(包含来自我市一些十字路口的stream量数据):
... "2011-12-17 16:00": { "local": "Av. Protásio Alves; esquina Ramiro Barcelos", "coord": "-30.036916,-51.208093", "sentido": "bairro-centro", "veiculos": "automotores", "modalidade": "semaforo 50-15", "regime": "típico", "pistas": "2+c", "medicoes": [ [32, 50], [40, 50], [29, 50], [32, 50], [35, 50] ] }, "2011-12-19 08:38": { "local": "R. Fernandes Vieira; esquina Protásio Alves", "coord": "-30.035535,-51.211079", "sentido": "único", "veiculos": "automotores", "modalidade": "semáforo 30-70", "regime": "típico", "pistas": "3", "medicoes": [ [23, 30], [32, 30], [33, 30], [32, 30] ] } ...
而且我已经用这些Python代码行build立了一个很好的数据库:
import sqlite3 db = sqlite3.connect("fluxos.sqlite") c = db.cursor() c.execute('''create table medicoes (timestamp text primary key, local text, coord text, sentido text, veiculos text, modalidade text, pistas text)''') c.execute('''create table valores (id integer primary key, quantidade integer, tempo integer, foreign key (id) references medicoes(timestamp))''')
但问题是,当我准备用c.execute("insert into medicoes values(?,?,?,?,?,?,?)" % keys)
来插入实际数据的行时,我意识到因为从JSON文件加载的字典没有特殊的顺序,所以它没有正确映射到数据库的列顺序。
所以,我问:“我应该使用哪种策略/方法来以编程方式读取JSON文件中每个”块“(在本例中为”local“,”coord“,”sentido“,”veiculos“,”modalidade “,”政权“,”pistas“和”medicoes“),按照相同顺序创build数据库,然后插入具有适当值的行。
我对Python有一个很好的经验,但是刚刚开始使用SQL,所以我想要一些关于良好实践的build议,而不一定是一个好的配方。
谢谢阅读!
你有这个Python代码:
c.execute("insert into medicoes values(?,?,?,?,?,?,?)" % keys)
我认为应该是这样
c.execute("insert into medicoes values (?,?,?,?,?,?,?)", keys)
因为%
运算符期望在其左边的string包含格式化代码。
现在所有你需要做的工作是keys
是一个元组(或列表),其中包含按照正确顺序排列的新行的值。 考虑下面的Python代码:
import json traffic = json.load(open('xxx.json')) columns = ['local', 'coord', 'sentido', 'veiculos', 'modalidade', 'pistas'] for timestamp, data in traffic.iteritems(): keys = (timestamp,) + tuple(data[c] for c in columns) print str(keys)
当我用你的示例数据运行这个时,我得到:
(u'2011-12-19 08:38', u'R. Fernandes Vieira; esquina Prot\xe1sio Alves', u'-30.035535,-51.211079', u'\xfanico', u'automotores', u'sem\xe1foro 30-70', u'3') (u'2011-12-17 16:00', u'Av. Prot\xe1sio Alves; esquina Ramiro Barcelos', u'-30.036916,-51.208093', u'bairro-centro', u'automotores', u'semaforo 50-15', u'2+c')
这似乎是你需要的元组。
你可以添加必要的sqlite代码,如下所示:
import json import sqlite3 traffic = json.load(open('xxx.json')) db = sqlite3.connect("fluxos.sqlite") query = "insert into medicoes values (?,?,?,?,?,?,?)" columns = ['local', 'coord', 'sentido', 'veiculos', 'modalidade', 'pistas'] for timestamp, data in traffic.iteritems(): keys = (timestamp,) + tuple(data[c] for c in columns) c = db.cursor() c.execute(query, keys) c.close()
编辑:如果你不想硬编码列的列表,你可以做这样的事情:
import json traffic = json.load(open('xxx.json')) someitem = traffic.itervalues().next() columns = list(someitem.keys()) print columns
当我运行它打印:
[u'medicoes', u'veiculos', u'coord', u'modalidade', u'sentido', u'local', u'pistas', u'regime']
你可以像这样使用它:
import json import sqlite3 db = sqlite3.connect('fluxos.sqlite') traffic = json.load(open('xxx.json')) someitem = traffic.itervalues().next() columns = list(someitem.keys()) columns.remove('medicoes') columns.remove('regime') query = "insert into medicoes (timestamp,{0}) values (?{1})" query = query.format(",".join(columns), ",?" * len(columns)) print query for timestamp, data in traffic.iteritems(): keys = (timestamp,) + tuple(data[c] for c in columns) c = db.cursor() c.execute(query) c.close()
当我尝试使用示例数据时,此代码打印的查询是这样的:
insert into medicoes (timestamp,veiculos,coord,modalidade,sentido,local,pistas) values (?,?,?,?,?,?,?)