将JSON转换为SQLite表

rkkpypqq  于 11个月前  发布在  SQLite
关注(0)|答案(2)|浏览(132)

我想将我创建的JSON文件转换为SQLite数据库。
我的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"
    },
"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"
    }
}

字符串
我用下面几行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))''')


如何以编程方式从JSON文件中的每个“块”中读取键(在本例中,“local”,“coord”,“sentido”,“veiculos”,“modalidade”,“regime”,“pistas”和“medicoes”),以相同的顺序创建列数据库,然后插入具有正确值的行?

z18hc3ub

z18hc3ub1#

你有这样的Python代码:

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

字符串
我觉得应该是

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


因为%运算符期望其左边的字符串包含格式化代码。
现在,您需要做的就是让keys成为一个元组(或列表),其中包含medicoes表中新行的值,并按正确的顺序排列。考虑以下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 (?,?,?,?,?,?,?)

qgzx9mmu

qgzx9mmu2#

使用流行的数据操作库pandas,将json转换为SQLite表非常容易,因为很多处理都是由pandas完成的。基本上,json文件可以使用pandas.read_json转换为pandas DataFrame,然后我们可以简单地过滤所需的列并使用to_sql转储到SQLite表中。

import sqlite3
import pandas as pd

con = sqlite3.connect('data/fluxos.sqlite')
(
    pd.read_json('data/my_json.json', orient='index')
    .filter(['local', 'coord', 'sentido', 'veiculos', 'modalidade', 'pistas'])
    .to_sql('medicoes', con, index_label='timestamp', dtype={'timestamp': 'TEXT PRIMARY KEY'}, if_exists='append')
)
con.close()

字符串
但是,如果你不想坚持使用内置库,那么你可以预先处理数据,并使用executemany让sqlite3处理循环,而不是显式地打开/关闭连接并逐个插入每行:

import json
import sqlite3

with open('data/my_json.json') as f:
    my_json = json.load(f)

columns = ['local', 'coord', 'sentido', 'veiculos', 'modalidade', 'pistas']
processed_data = [(timestamp, *(data[c] for c in columns)) for timestamp, data in my_json.items()]

con = sqlite3.connect('data/fluxos.sqlite')
cur = con.cursor()

cur.execute('''
CREATE TABLE medicoes (
    timestamp TEXT PRIMARY KEY,
    local TEXT,
    coord TEXT,
    sentido TEXT,
    veiculos TEXT,
    modalidade TEXT,
    pistas TEXT)
''')

cur.executemany("INSERT INTO medicoes VALUES (?, ?, ?, ?, ?, ?, ?)", processed_data)
con.commit()
cur.close()
con.close()

相关问题