Поиск значений в SQLite с помощью apsw на Python

Почему этот код возвращает строку 'p',8,9когда я попросил его вернуть только те строки, где первый элемент> затем 3? Первый элемент этой строки - "p". Я заметил, что этот метод отлично работает с int, но если сравниваемым элементом является str, это происходит. Зачем? И как это исправить (как я могу получить только те строки, в которых какой-то элемент> 3, например)? Мне больше интересно узнать, почему это происходит.

Код:

import apsw


connection=apsw.Connection("database01")
cursor=connection.cursor()
cursor.execute("create table foo(a,b,c)")
cursor.execute("insert into foo values(1,2,3);insert into foo values(4,5,6);insert into foo values(7,8,9);insert into foo values('p',8,9)")


for x,y,z in cursor.execute("select a,b,c from foo"):
    print (cursor.getdescription())  # shows column names and declared types
    print (x,y,z)


def rowtrace(*results):
    """Called with each row of results before they are handed off.  You can return None to
    cause the row to be skipped or a different set of values to return"""
    print ("Row:",results)
    return results

cursor.setrowtrace(rowtrace)
for row in cursor.execute("select a,b from foo where a>3"):
     pass

Выход:

(('a', None), ('b', None), ('c', None))
1 2 3
(('a', None), ('b', None), ('c', None))
4 5 6
(('a', None), ('b', None), ('c', None))
7 8 9
(('a', None), ('b', None), ('c', None))
p 8 9
Row: (<apsw.Cursor object at 0x7fab057f92b0>, (4, 5))
Row: (<apsw.Cursor object at 0x7fab057f92b0>, (7, 8))
Row: (<apsw.Cursor object at 0x7fab057f92b0>, ('p', 8))

Источник: http://www.cesarkallas.net/arquivos/apostilas/python/exemplos/APSW%20-%20Another%20Python%20SQLite%20Wrapper.htm

1 ответ

Решение

"Почему" можно найти в документации sqlite3 о сравнительных выражениях. Он соответствует примеру сравнения для столбца а.

- Поскольку столбец "a" имеет сходство с текстом, числовые значения в
правой части сравнений преобразуются в текст до
того, как происходит сравнение.
ВЫБЕРИТЕ a < 40, a < 60, a < 600 ИЗ t1;
0|1|1

По выбору будет CAST a до целого числа перед сравнением, т.е. WHERE cast(a as int) > 3. Это только вариант, потому что это не было бы идеальным решением в зависимости от варианта использования. Другой вариант - ограничить верхний предел, напримерWHERE a between 3 and 99999999; снова не идеальное решение.

Другие вопросы по тегам