Чтобы получить количество записей, возвращаемых SSDictCursor
или SSCursor
, у вас есть только следующие варианты:
Получить весь результат и сосчитать его, используя len()
, что побеждаетцель использования SSDictCursor
или SSCursor
в первую очередь;
Подсчитывать строки самостоятельно при их итерации по ним, что означает, что вы не будете знать счет до тех пор, пока не нажметеконец (вряд ли будет практичным);или
Запустите дополнительный отдельный запрос COUNT(*)
.
Я настоятельно рекомендую третий вариант.Это очень быстро, если все, что вы делаете, это SELECT COUNT(*) FROM table;
.Это было бы медленнее для некоторых более сложных запросов, но при правильном индексировании оно все равно должно быть достаточно быстрым для большинства целей.
Кроме того, возвращаемое значение, которое вы видите, равно правильно;по крайней мере, что касается API MySQL C.
В соответствии с API-интерфейсом DB Python, определенным в PEP 249, атрибут rowcount равен -1, если количество строк последней операции не может быть определеноинтерфейс .@glglgl объяснил, почему количество строк не может быть определено в их ответе:
Внутренне, SSDictCursor
использует mysql_use_result()
, что позволяет серверу начать передачу данных до завершения сбора.
Другими словами, сервер не знает, сколько строк он в конечном итоге собирается извлечь.При выполнении запроса MySQLdb
сохраняет возвращаемое значение mysql_affected_rows()
в атрибуте курсора rowcount
.Поскольку счетчик не определен, эта функция возвращает -1
как длинное целое число без знака (my_ulonglong
), числовой тип, который доступен в модуле ctypes
стандартной библиотеки:
>>> from ctypes import c_ulonglong
>>> n = c_ulonglong(-1)
>>> n.value
18446744073709551615L
Быстрая и грязная альтернатива ctypes
, когда вы знаете, что всегда будете иметь дело с 64-разрядным целым числом без знака, это:
>>> -1 & 0xFFFFFFFFFFFFFFFF
18446744073709551615L
Было бы здорово, если быMySQLdb
проверил это возвращаемое значение и дал целое число со знаком, которое вы ожидаете увидеть, но, к сожалению, это не так.