#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) — ничего сложного; с вашим кодом и моим я по какой-то причине получаю только один результат