Je souhaite convertir un fichier JSON que j'ai créé en une base de données SQLite.
Mon intention est de décider plus tard quel conteneur de données et point d'entrée est le meilleur, json (saisie de données via l'éditeur de texte) ou SQLite (saisie de données via des GUI de type tableur comme SQLiteStudio).
Mon fichier json est comme ceci (contenant les données de trafic de certains carrefours dans ma ville):
...
"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]
]
}
...
Et j'ai créé une base de données Nice avec une relation un-à-plusieurs avec ces lignes de 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))''')
MAIS le problème est que, lorsque je me préparais à insérer les lignes avec des données réelles avec quelque chose comme c.execute("insert into medicoes values(?,?,?,?,?,?,?)" % keys)
, je me suis rendu compte que, puisque le dict chargé à partir du fichier JSON n'a pas d'ordre spécial, il ne correspond pas correctement à l'ordre des colonnes de la base de données.
Je demande donc: "quelle stratégie/méthode dois-je utiliser pour lire par programme les clés de chaque" bloc "du fichier JSON (dans ce cas," local "," coord "," sentido "," veiculos "," modalidade "," régime "," pistas "et" médecins "), créez la base de données avec les colonnes dans le même ordre, puis insérez les lignes avec les valeurs appropriées"?
J'ai une bonne expérience avec Python, mais je ne fais que commencer avec SQL, donc j'aimerais avoir des conseils sur les bonnes pratiques, et pas nécessairement une recette prête.
Vous avez ce code python:
c.execute("insert into medicoes values(?,?,?,?,?,?,?)" % keys)
qui je pense devrait être
c.execute("insert into medicoes values (?,?,?,?,?,?,?)", keys)
puisque le %
operator s'attend à ce que la chaîne à gauche contienne des codes de formatage.
Maintenant, tout ce dont vous avez besoin pour que cela fonctionne est que keys
soit un Tuple (ou une liste) contenant les valeurs de la nouvelle ligne de la table medicoes dans le bon ordre. Considérez le code python suivant:
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)
Lorsque je lance cela avec vos exemples de données, j'obtiens:
(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')
qui semblent être les tuples dont vous avez besoin.
Vous pouvez ajouter le code sqlite nécessaire avec quelque chose comme ceci:
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()
Modifier: si vous ne voulez pas coder en dur la liste des colonnes, vous pouvez faire quelque chose comme ceci:
import json
traffic = json.load(open('xxx.json'))
someitem = traffic.itervalues().next()
columns = list(someitem.keys())
print columns
Lorsque je lance cela, il affiche:
[u'medicoes', u'veiculos', u'coord', u'modalidade', u'sentido', u'local', u'pistas', u'regime']
Vous pouvez l'utiliser avec quelque chose comme ceci:
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()
La requête que ce code imprime lorsque je l'essaye avec vos exemples de données est quelque chose comme ceci:
insert into medicoes (timestamp,veiculos,coord,modalidade,sentido,local,pistas) values (?,?,?,?,?,?,?)