2012-01-10 53 views
36

我想將我創建的JSON文件轉換爲SQLite數據庫。在Python中將JSON轉換爲SQLite - 如何正確地將json鍵映射到數據庫列?

我的本意是後來決定哪些數據容器和切入點是最好的,JSON(通過文本編輯器數據輸入)或SQLite的(通過類似電子表格的圖形用戶界面的數據錄入像SQLiteStudio)。

我的JSON文件是這樣的(含有一些十字路口在我的城市交通數據):

... 
"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代碼這些行一個一對多的關係:

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「),按照相同順序創建數據庫,然後插入具有適當值的行。

我有使用Python公平的經驗,但我只是用SQL開始,所以我想有關於一些好的做法輔導,而不一定是一個現成的配方。

回答

36

你有這樣的Python代碼:

c.execute("insert into medicoes values(?,?,?,?,?,?,?)" % keys) 

,我認爲應該是

c.execute("insert into medicoes values (?,?,?,?,?,?,?)", keys) 

% operator預計字符串的左側包含格式代碼。

現在,您需要完成此項工作的所有內容都是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') 

這似乎是您所需要的元組。

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() 

編輯:如果你不想硬編碼列的列表,你可以做這樣的事情:

你可以像這樣的東西添加必要的sqlite的代碼

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 (?,?,?,?,?,?,?) 
+0

我認爲你的回答包含了大部分的我想做。我唯一剩下的問題是'columns'是硬編碼的,我希望從文件中讀取字符串。最理想的是,它們應該是相同的順序。你怎麼看? – heltonbiker 2012-01-10 23:43:29

+0

我用非硬編碼的列列表編輯了我的答案。 – srgerg 2012-01-11 00:01:54

相關問題