db = sqlite.connect("test.sqlite")
res = db.execute("select * from table")
Com a iteração, obtenho listas correspondentes às linhas.
for row in res:
print row
Posso obter o nome das colunas
col_name_list = [tuple[0] for tuple in res.description]
Mas existe alguma função ou configuração para obter dicionários em vez de lista?
{'col1': 'value', 'col2': 'value'}
ou eu tenho que fazer sozinho?
python
sql
sqlite
dictionary
dataformat
Meloun
fonte
fonte
Respostas:
Você pode usar row_factory , como no exemplo da documentação:
ou siga o conselho fornecido logo após este exemplo nos documentos:
fonte
SELECT 1 AS "dog[cat]"
, ocursor
não terá a descrição correta para criar um dicionário.connection.row_factory = sqlite3.Row
e tenteiconnection.row_factory = dict_factory
conforme mostrado, mascur.fetchall()
ainda está me dando uma lista de tuplas - alguma ideia de por que isso não está funcionando?collections.namedtuple
. Quando eu usocur.fetchmany()
, recebo entradas como<sqlite3.Row object at 0x...>
.Achei que tivesse respondido a essa pergunta, embora a resposta seja parcialmente mencionada nas respostas de Adam Schmideg e Alex Martelli. Para que outros como eu que tenham a mesma pergunta, encontrem a resposta facilmente.
fonte
fetchall()
parece retornarsqlite3.Row
objetos. No entanto, estes podem ser convertidos em um dicionário simplesmente usandodict()
:result = [dict(row) for row in c.fetchall()]
.Mesmo usando a classe sqlite3.Row - você ainda não pode usar a formatação de string na forma de:
Para superar isso, uso uma função auxiliar que pega a linha e converte em um dicionário. Eu só uso isso quando o objeto de dicionário é preferível ao objeto Row (por exemplo, para coisas como formatação de string, onde o objeto Row não suporta nativamente a API do dicionário também). Mas use o objeto Row todas as outras vezes.
fonte
print "%(id)i - %(name)s: %(value)s" % dict(row)
Depois de se conectar ao SQLite:
con = sqlite3.connect(.....)
é suficiente apenas executar:Voila!
fonte
Do PEP 249 :
Então, sim, faça você mesmo.
fonte
Versão mais curta:
fonte
O mais rápido em meus testes:
vs:
Você decide :)
fonte
Soluções semelhantes às mencionadas antes, mas mais compactas:
fonte
db.row_factory = sqlite3.Row
não funcionou para mim (pois resultou em um JSON TypeError)Conforme mencionado pela resposta de @gandalf, deve-se usar
conn.row_factory = sqlite3.Row
, mas os resultados não são dicionários diretos . É necessário adicionar um "elenco" adicional aodict
último loop:fonte
Acho que você estava no caminho certo. Vamos manter isso muito simples e completo o que você estava tentando fazer:
A desvantagem é que
.fetchall()
, se a sua mesa for muito grande, o consumo de memória é um assassinato . Mas para aplicativos triviais que lidam com meros poucos milhares de linhas de texto e colunas numéricas, essa abordagem simples é boa o suficiente.Para assuntos sérios, você deve olhar para as fábricas em linha, como proposto em muitas outras respostas.
fonte
Ou você pode converter sqlite3.Rows em um dicionário da seguinte maneira. Isso fornecerá um dicionário com uma lista para cada linha.
fonte
Uma alternativa genérica, usando apenas três linhas
Mas se sua consulta não retornar nada, resultará em erro. Nesse caso...
ou
fonte
O resultado é definitivamente verdadeiro, mas não conheço o melhor.
fonte
Dicionários em python fornecem acesso arbitrário aos seus elementos. Portanto, qualquer dicionário com "nomes", embora possa ser informativo por um lado (também conhecido como quais são os nomes de campo), "desordena" os campos, o que pode ser indesejado.
A melhor abordagem é colocar os nomes em uma lista separada e combiná-los com os resultados você mesmo, se necessário.
Lembre-se também de que os nomes, em todas as abordagens, são os nomes que você forneceu na consulta, não os nomes no banco de dados. A exceção é o
SELECT * FROM
Se sua única preocupação é obter os resultados usando um dicionário, então, definitivamente, use o
conn.row_factory = sqlite3.Row
(já declarado em outra resposta).fonte