Не удается выдать все строки в таблице в качестве ключа, значения с использованием sqlite3

#python #sqlite #key-value-store

#python #sqlite #ключ-значение-хранилище

Вопрос:

По какой-то причине я не могу выполнить итерацию по всем строкам в таблице, когда я получаю результат из инструкции SELECT в sqlite3. Когда я возвращаю результат в виде списка, у меня есть все строки.

Я не уверен, что я делаю неправильно…

Приведенный ниже код выдает только одну строку, если я использую ее где-то снаружи:

 def items(self):
        for row in self._cursor.execute('SELECT key, value FROM dict_table'):
            yield (self.loads(row[0]), self.loads(row[1]))
  

Если я оберну возвращаемое значение в виде списка, я получу все строки:

 def iteritems(self):
        for row in self._cursor.execute('SELECT key, value FROM dict_table'):
            yield (self.loads(row[0]), self.loads(row[1]))


def items(self):
        return(list(self.iteritems()))
  

В идеале, я хочу использовать его только как генератор, а не получать весь список

 def items(self):
        for row in self._cursor.execute('SELECT key, value FROM dict_table'):
            yield (self.loads(row[0]), self.loads(row[1]))

  

Где-то еще в коде я просто хочу иметь возможность запускать:

 
for key, val in self.items():
    print(val/key)

  

Редактировать:

Я также попробовал следующее решение без какого-либо успеха

 def iteritems(self):
        for row in self._cursor.execute('SELECT key, value FROM dict_table'):
            yield (self.loads(row[0]), self.loads(row[1]))


def items(self):
        yield from (self.iteritems())
  

Он также по-прежнему возвращает мне 1 строку, когда я пытаюсь выполнить итерацию по элементам

Комментарии:

1. Потому что 1-я просто выполняет итерацию один раз, следовательно, дает первые 2 строки, а 2-я выполняет итерацию до конца, следовательно, дает вам все строки. Yield выдает вам следующий элемент в списке

2. В первом случае я завершаю цикл for. Мне нужно было бы вернуть генератор, чтобы не возвращать весь список. Я делаю следующее: для элемента в self.iteritmes(): берем элемент и выполняем работу, но я получаю только два элемента вместо 50

3. Каждый раз он возвращает одни и те же строки … верно?

4. Да, только одна строка.

5. в чем проблема? ваша функция выдает значения, следовательно, почему, когда вы оборачиваете ее в вызов списка, она использует генератор сразу.

Ответ №1:

Все, о чем я могу думать, это о том, что, возможно, вы повторно используете один и тот же курсор для более чем одного запроса одновременно, и более ранний итератор останавливается, поскольку курсор использовался для более позднего запроса.

Чтобы исправить это, вы должны создавать новый курсор для каждого запроса.

Комментарии:

1. Да, у меня такое же чувство, потому что, когда я использую connection.execute вместо cursor.execute, это дает мне немного другие результаты. Более того, когда я использую c2 = connections.cursor(), а затем запускаю метод execute, мое приложение зависает. Я не уверен, что является причиной этого. В противном случае я повторно использую тот же курсор, но все вызовы синхронны и последовательны. Я бы ожидал, что курсор будет возвращать разное количество строк каждый раз, если бы у меня была проблема с параллелизмом.

2. Я попробую снова создать курсор, но по какой-то причине он, похоже, зависает

Ответ №2:

Это потому, что вы извлекаете строки снова и снова. пожалуйста, попробуйте приведенное ниже решение

 def items(self):
        rows = self._cursor.execute('SELECT key, value FROM dict_table')
        for row in rows:
            yield (row)
  

Комментарии:

1. К сожалению, это не сработало : ( оператор yield не должен снова запускать execute и извлекать строки, он должен вернуться к первому оператору в yield, который является self.loads(строка[0]), self.loads(строка[1]). Если бы он извлекал их снова и снова, я должен был бы застрять в бесконечном цикле?

2. Я обновил свое решение. пожалуйста, попробуйте это. он будет возвращать по одной строке за раз. если вы хотите вернуть все строки вместе, просто удалите цикл for и верните строки вместо этого.

3. К сожалению, я не хочу возвращать все строки, поскольку мне нужно вернуть итерацию, но как генератор, а не как весь список. Я попробовал ваше модифицированное решение, и когда я перебираю элементы (для элемента в self.items()), я получаю только один элемент. Я озадачен: O

4. не могли бы вы, пожалуйста, опубликовать этот код, в котором вы перебираете элементы?

5. для k, v в self.items(): print(v / k) — ничего сложного; с вашим кодом и моим я по какой-то причине получаю только один результат