Sqlite и Python - вернуть словарь, используя fetchone ()? - PullRequest
26 голосов
/ 01 мая 2009

Я использую sqlite3 в Python 2.5. Я создал таблицу, которая выглядит следующим образом:

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

Я получаю к нему что-то вроде этого:

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

Я хотел бы, чтобы fetchone (или другой метод) возвращал словарь, а не список, чтобы я мог ссылаться на поле по имени, а не по позиции. Например:

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

Я знаю, что вы можете сделать это с MySQL, но кто-нибудь знает, как это сделать с SQLite?

Спасибо !!!

Ответы [ 7 ]

73 голосов
/ 26 марта 2010

На самом деле есть опция для этого в sqlite3. Измените элемент row_factory объекта подключения на sqlite3.Row:

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

или

conn.row_factory = sqlite3.Row

Это позволит вам получить доступ к элементам строки по имени - в стиле словаря - или по индексу. Это гораздо эффективнее, чем создание собственного обходного пути.

18 голосов
/ 01 мая 2009

Как я делал это в прошлом:

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

Затем вы устанавливаете это в своем соединении:

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

Это работает в pysqlite-2.4.1 и python 2.5.4.

9 голосов
/ 29 января 2013

Недавно я пытался сделать нечто подобное при использовании sqlite3.Row (). Хотя sqlite3.Row () отлично подходит для обеспечения словарного интерфейса или интерфейса, похожего на кортеж, он не работал, когда я передавал строки с помощью ** kwargs. Итак, нужен быстрый способ преобразования его в словарь. Я понял, что объект Row () можно преобразовать в словарь, просто используя 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))

Или в Python 3, проще:

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

Аналогично, вы можете использовать команду dbCursor.fetchall () и преобразовать весь набор строк в список словарей в цикле for.

5 голосов
/ 01 мая 2009

Конечно, создайте DictConnection и DictCursor, как объяснено и показано, например, в http://trac.edgewall.org/pysqlite.org-mirror/wiki/PysqliteFactories.

2 голосов
/ 04 мая 2009

Я знаю, что вы не спрашиваете об этом, но почему бы просто не использовать sqlalchemy для создания формы для базы данных? тогда вы можете делать такие вещи, как,


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

в качестве дополнительного бонуса ваш код будет легко переноситься на альтернативную базу данных, а соединения и прочее будут управляться бесплатно.

1 голос
/ 23 сентября 2013

Я использовал это:

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

Тогда вы можете сделать это:

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

Теперь d - это словарь, в котором ключи user, а значения city. Это также работает для group by

0 голосов
/ 27 августа 2018

Я использую что-то вроде этого:

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

с этим:

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() - это класс, который наследуется от SqliteRow. Класс SqliteRow является базовым классом для каждого объекта, который я хочу вернуть запросом. Каждый столбец становится атрибутом и регистрируется в списке fields. Функция to_tuple используется для изменения всего объекта в форму, подходящую для запросов (просто передайте весь объект и забудьте).

Чтобы получить разные типы классов этой функции. Вам необходимо создать фабричный объект, который будет генерировать объекты на основе списка полей (например: dict с {some_unique_value_made_of_fields: class})

Таким образом, я получаю простой ORM.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...