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à :-)

1voto

joe Points 11

Obtenir les résultats de la requête

output_obj = con.execute(query)
results = output_obj.fetchall()

Option 1) Boucle explicite avec fermeture éclair

for row in results:
    col_names = [tup[0] for tup in output_obj.description]
    row_values = [i for i in row]
    row_as_dict = dict(zip(col_names,row_values))

Option 2) Boucle plus rapide avec Dict Comp

for row in results:
    row_as_dict = {output_obj.description[i][0]:row[i] for i in range(len(row))}

0voto

andere Points 6

Ou vous pouvez convertir le sqlite3.Rows en dictionnaire comme suit. Cela donnera un dictionnaire avec une liste pour chaque ligne.

    def from_sqlite_Row_to_dict(list_with_rows):
    ''' Turn a list with sqlite3.Row objects into a dictionary'''
    d ={} # the dictionary to be filled with the row data and to be returned

    for i, row in enumerate(list_with_rows): # iterate throw the sqlite3.Row objects            
        l = [] # for each Row use a separate list
        for col in range(0, len(row)): # copy over the row date (ie. column data) to a list
            l.append(row[col])
        d[i] = l # add the list to the dictionary   
    return d

0voto

Macabeus Points 1314

Une alternative générique, utilisant seulement trois lignes

def select_column_and_value(db, sql, parameters=()):
    execute = db.execute(sql, parameters)
    fetch = execute.fetchone()
    return {k[0]: v for k, v in list(zip(execute.description, fetch))}

con = sqlite3.connect('/mydatabase.db')
c = con.cursor()
print(select_column_and_value(c, 'SELECT * FROM things WHERE id=?', (id,)))

Mais si votre requête ne renvoie rien, il y aura une erreur. Dans ce cas...

def select_column_and_value(self, sql, parameters=()):
    execute = self.execute(sql, parameters)
    fetch = execute.fetchone()

    if fetch is None:
        return {k[0]: None for k in execute.description}

    return {k[0]: v for k, v in list(zip(execute.description, fetch))}

ou

def select_column_and_value(self, sql, parameters=()):
    execute = self.execute(sql, parameters)
    fetch = execute.fetchone()

    if fetch is None:
        return {}

    return {k[0]: v for k, v in list(zip(execute.description, fetch))}

0voto

user2138283 Points 25
import sqlite3

db = sqlite3.connect('mydatabase.db')
cursor = db.execute('SELECT * FROM students ORDER BY CREATE_AT')
studentList = cursor.fetchall()

columnNames = list(map(lambda x: x[0], cursor.description)) #students table column names list
studentsAssoc = {} #Assoc format is dictionary similarly

#THIS IS ASSOC PROCESS
for lineNumber, student in enumerate(studentList):
    studentsAssoc[lineNumber] = {}

    for columnNumber, value in enumerate(student):
        studentsAssoc[lineNumber][columnNames[columnNumber]] = value

print(studentsAssoc)

Le résultat est certainement vrai, mais je ne connais pas le meilleur.

0voto

ilias iliadis Points 131

Les dictionnaires en python permettent un accès arbitraire à leurs éléments. Ainsi, tout dictionnaire avec des "noms", bien qu'il puisse être informatif d'un côté (par exemple, quels sont les noms des champs), "désordonne" les champs, ce qui peut être indésirable.

La meilleure approche est d'obtenir les noms dans une liste séparée et de les combiner ensuite avec les résultats par vous-même, si nécessaire.

try:
         mycursor = self.memconn.cursor()
         mycursor.execute('''SELECT * FROM maintbl;''')
         #first get the names, because they will be lost after retrieval of rows
         names = list(map(lambda x: x[0], mycursor.description))
         manyrows = mycursor.fetchall()

         return manyrows, names

Rappelez-vous également que les noms, dans toutes les approches, sont les noms que vous avez fournis dans la requête, et non les noms dans la base de données. L'exception est l'approche SELECT * FROM

Si votre seule préoccupation est d'obtenir les résultats à l'aide d'un dictionnaire, alors utilisez sans hésiter la fonction conn.row_factory = sqlite3.Row (déjà indiqué dans une autre réponse).

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