Pergunta

Eu estou usando sqlite3 em python 2.5. Eu criei uma tabela que se parece com isso:

   create table votes (
      bill text,
      senator_id text,
      vote text)

Estou acessá-lo com algo parecido com isto:

v_cur.execute("select * from votes")
row = v_cur.fetchone()
bill = row[0]
senator_id = row[1]
vote = row[2]

O que eu gostaria de ser capaz de fazer é ter fetchone (ou algum outro método) retornar um dicionário, em vez de uma lista, para que eu possa se referir ao campo pelo nome, em vez de posição. Por exemplo:

bill = row['bill'] 
senator_id = row['senator_id']
vote = row['vote']

Eu sei que você pode fazer isso com o MySQL, mas alguém sabe como fazê-lo com SQLite?

Thanks !!!

Foi útil?

Solução

A maneira que eu tenho feito isso no passado:

def dict_factory(cursor, row):
    d = {}
    for idx,col in enumerate(cursor.description):
        d[col[0]] = row[idx]
    return d

Em seguida, você configurá-lo em sua conexão:

from pysqlite2 import dbapi2 as sqlite
conn = sqlite.connect(...)
conn.row_factory = dict_factory

Isso funciona sob pysqlite-2.4.1 e python 2.5.4.

Outras dicas

Há realmente uma opção para isso no sqlite3. Altere o membro row_factory do objeto de conexão para sqlite3.Row:

conn = sqlite3.connect('db', row_factory=sqlite3.Row)

ou

conn.row_factory = sqlite3.Row

Isto irá permitir-lhe elementos de linha de acesso por nome - dicionário de estilo - ou pelo índice. Isso é muito mais eficiente do que criar o seu próprio trabalho-around.

Recentemente eu estava tentando fazer algo semelhante ao usar sqlite3.Row (). Enquanto sqlite3.Row () é ótimo para fornecer um dicionário-como interface ou uma tupla como interface, que não funcionou quando eu canalizada na linha usando kwargs **. Então, precisava de uma maneira rápida de convertê-lo em um dicionário. Compreendi que o objecto Fila () pode ser convertido a um dicionário simplesmente usando itertools.

Python 2:

db.row_factory = sqlite3.Row
dbCursor = db.cursor()
dbCursor.execute("SELECT * FROM table")
row = dbCursor.fetchone()

rowDict = dict(itertools.izip(row.keys(), row))

Ou em Python 3, mais simplesmente:

dbCursor = db.cursor()
dbCursor.execute("SELECT * FROM table")
row = dbCursor.fetchone()
rowDict = dict(zip([c[0] for c in dbCursor.description], row))

Da mesma forma, você pode usar o comando dbCursor.fetchall () e converter todo o conjunto de linhas a uma lista de dicionários em um loop.

Claro, tornar-se um DictConnection e DictCursor como explicado e mostrado em http: //trac.edgewall.org/pysqlite.org-mirror/wiki/PysqliteFactories por exemplo.

Eu sei que você não está pedindo isso, mas por que não usar sqlalchemy para construir um ORM para o banco de dados? então você pode fazer coisas como,


entry = model.Session.query(model.Votes).first()
print entry.bill, entry.senator_id, entry.vote

como um bônus adicional o seu código será facilmente transportável para um banco de dados alternativo, e as conexões e outros enfeites será gerido de forma gratuita.

Eu usei isso:

def get_dict(sql):
    return dict(c.execute(sql,()).fetchall())

Em seguida, você pode fazer isso:

c = conn.cursor()
d = get_dict("select user,city from vals where user like 'a%'");

Agora d é um dicionário onde as chaves são user e os valores são city. Isso também funciona para group by

Eu uso algo como isto:

class SqliteRow(object):
    def __init__(self):
        self.fields = []

    def add_field(self, name, value):
        self.fields.append(name)
        setattr(self, name, value)

    def to_tuple(self):
        return tuple([getattr(self, x) for x in self.fields])

com este:

def myobject_factory(cursor, row):
    myobject= MyObject()
    for idx, col in enumerate(cursor.description):
        name, value = (col[0], row[idx])

        myobject.add_field(name, value)
    return myobject

MyObject() é uma classe que herda de SqliteRow. classe SqliteRow é uma classe base para todos os objetos que eu quero ter retornado por uma consulta. Cada coluna torna-se um atributo e é registrado na lista fields. to_tuple função é usada para mudar todo o objeto para uma forma adequada para consultas (simplesmente passar todo o objeto e esquecer).

Para obter diferentes tipos de classe de tal função. Você precisaria fazer um objeto fábrica, que irá gerar objetos com base na lista de campos (por exemplo: dict com {some_unique_value_made_of_fields: class})

Desta forma, eu recebo um ORM simples.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top