with instalar has for fetchone fetchmany descargar attribute python sql sqlite dictionary dataformat

python - instalar - sqlite3 cursor object has no attribute commit



¿Cómo puedo obtener dict de la consulta sqlite? (10)

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

Con la iteración, obtengo listas en correspondencia con las filas.

for row in res: print row

Puedo obtener el nombre de las columnas

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

Pero, ¿hay alguna función o configuración para obtener diccionarios en lugar de list?

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

o tengo que hacerme a mi mismo?


De PEP 249 :

Question: How can I construct a dictionary out of the tuples returned by .fetch*(): Answer: There are several existing tools available which provide helpers for this task. Most of them use the approach of using the column names defined in the cursor attribute .description as basis for the keys in the row dictionary. Note that the reason for not extending the DB API specification to also support dictionary return values for the .fetch*() methods is that this approach has several drawbacks: * Some databases don''t support case-sensitive column names or auto-convert them to all lowercase or all uppercase characters. * Columns in the result set which are generated by the query (e.g. using SQL functions) don''t map to table column names and databases usually generate names for these columns in a very database specific way. As a result, accessing the columns through dictionary keys varies between databases and makes writing portable code impossible.

Entonces sí, hazlo tú mismo.


Incluso utilizando la clase sqlite3.Row-- todavía no puede usar el formato de cadena en la forma de:

print "%(id)i - %(name)s: %(value)s" % row

Para superar esto, utilizo una función auxiliar que toma la fila y la convierte a un diccionario. Solo uso esto cuando el objeto de diccionario es preferible al objeto Fila (por ejemplo, para cosas como el formato de cadenas donde el objeto Row no admite de forma nativa la API de diccionario también). Pero use el objeto Fila todas las demás veces.

def dict_from_row(row): return dict(zip(row.keys(), row))


Lo más rápido en mis pruebas:

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)

Tú decides :)


O puede convertir el sqlite3.Rows en un diccionario de la siguiente manera. Esto dará un diccionario con una lista para cada fila.

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


Pensé que respondía a esta pregunta a pesar de que la respuesta se menciona en parte en las respuestas de Adam Schmideg y Alex Martelli. Para que otros como yo que tienen la misma pregunta encuentren la respuesta fácilmente.

conn = sqlite3.connect(":memory:") #This is the important part, here we are setting row_factory property of #connection object to sqlite3.Row(sqlite3.Row is an implementation of #row_factory) conn.row_factory = sqlite3.Row c = conn.cursor() c.execute(''select * from stocks'') result = c.fetchall() #returns a list of dictionaries, each item in list(each dictionary) #represents a row of the table


Puede usar row_factory , como en el ejemplo en los documentos:

import sqlite3 def dict_factory(cursor, row): d = {} for idx, col in enumerate(cursor.description): d[col[0]] = row[idx] return d con = sqlite3.connect(":memory:") con.row_factory = dict_factory cur = con.cursor() cur.execute("select 1 as a") print cur.fetchone()["a"]

o siga los consejos que se dan justo después de este ejemplo en los documentos:

Si devolver una tupla no es suficiente y desea tener acceso basado en el nombre a las columnas, debería considerar establecer row_factory en el tipo de sqlite3.Row altamente optimizado. Row proporciona acceso basado en nombres basado en índice y no sensible a mayúsculas y minúsculas a columnas con casi ninguna sobrecarga de memoria. Probablemente sea mejor que su propio enfoque basado en el diccionario personalizado o incluso una solución basada en db_row.


Similar a las soluciones antes mencionadas, pero más compacto:

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


Una alternativa genérica, usando solo tres líneas

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

Pero si su consulta no devuelve nada, dará lugar a un error. En este caso...

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

o

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


Versión más corta:

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


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)

El resultado es definitivamente cierto, pero no sé cuál es el mejor.