141 votes

Comment puis-je obtenir un dict à partir d'une requête sqlite ?

db = sqlite.connect("test.sqlite")
res = db.execute("select * from table")

Avec l'itération, j'obtiens des listes correspondant aux rangées.

for row in res:
    print row

Je peux obtenir le nom des colonnes

col_name_list = [tuple[0] for tuple in res.description]

Mais existe-t-il une fonction ou un paramètre permettant d'obtenir des dictionnaires au lieu d'une liste ?

{'col1': 'value', 'col2': 'value'}

ou que je dois faire moi-même ?

0 votes

7 votes

@vy32 : Cette question date de juillet 2010, celle dont vous avez donné le lien date de novembre 2010. C'est donc celle-là qui est fausse. Et comme on peut s'y attendre, le commentaire inverse a été mis sur celle-là :-)

3voto

M. Utku ALTINKAYA Points 1549

Version courte :

db.row_factory = lambda c, r: dict([(col[0], r[idx]) for idx, col in enumerate(c.description)])

3voto

Ran Aroussi Points 441

Le plus rapide sur mes tests :

conn.row_factory = lambda c, r: dict(zip([col[0] for col in c.description], r))
c = conn.cursor()

%timeit c.execute('SELECT * FROM table').fetchall()
19.8 µs ± 1.05 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)

vs :

conn.row_factory = lambda c, r: dict([(col[0], r[idx]) for idx, col in enumerate(c.description)])
c = conn.cursor()

%timeit c.execute('SELECT * FROM table').fetchall()
19.4 µs ± 75.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

C'est vous qui décidez :)

2voto

Falko Points 10901

Similaire aux solutions précédentes, mais plus compacte :

db.row_factory = lambda C, R: { c[0]: R[i] for i, c in enumerate(C.description) }

2voto

Basj Points 776

Comme mentionné par la réponse de @gandalf, il faut utiliser conn.row_factory = sqlite3.Row mais les résultats sont pas directement dictionnaires. Il faut ajouter un "cast" supplémentaire à dict dans la dernière boucle :

import sqlite3
conn = sqlite3.connect(":memory:")
conn.execute('create table t (a text, b text, c text)')
conn.execute('insert into t values ("aaa", "bbb", "ccc")')
conn.execute('insert into t values ("AAA", "BBB", "CCC")')
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('select * from t')
for r in c.fetchall():
    print(dict(r))

# {'a': 'aaa', 'b': 'bbb', 'c': 'ccc'}
# {'a': 'AAA', 'b': 'BBB', 'c': 'CCC'}

1voto

Tammi Points 56

Je pense que vous étiez sur la bonne voie. Restons très simples et complétons ce que vous avez essayé de faire :

import sqlite3
db = sqlite3.connect("test.sqlite3")
cur = db.cursor()
res = cur.execute("select * from table").fetchall()
data = dict(zip([c[0] for c in cur.description], res[0]))

print(data)

L'inconvénient est que .fetchall() ce qui a un impact négatif sur votre consommation de mémoire si votre table est très grande. Mais pour des applications triviales ne comportant que quelques milliers de lignes de texte et de colonnes numériques, cette approche simple est suffisante.

Pour les choses sérieuses, vous devriez vous pencher sur les fabriques de rangées, comme proposé dans de nombreuses autres réponses.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X