#python #psycopg2 #amazon-redshift #integer-overflow
#python #psycopg2 #amazon-redshift #целое число-переполнение
Вопрос:
Недавно я начал использовать модуль Python psycopg2
для работы с базой данных Redshift.
У меня есть определенный запрос, который вставляет много строк (около 100 миллиардов), и результаты курсора не совпадают:
cursor.execute("INSERT ...")
status_msg = cursor.statusmessage
row_count = cursor.rowcount
logging.info("status_message='%s', row_count=%d" % (status_msg, row_count))
Дает мне:
>>> status_message='INSERT 0 100791203475', row_count=2006955667
Для других больших запросов это также возвращает отрицательное число. Я почти уверен, что это связано с тем, что количество строк больше, чем может поместиться в int, но я не нашел способа это исправить.
Я попытался немного поэкспериментировать с Python int
s, но это не похоже на форматирование, вот проблема и многое другое, что возвращается psycopg2
:
>>> print "%d" % int(100791203475)
100791203475
Есть ли способ убедиться psycopg2
, что вернет правильное количество строк? Это ошибка в psycopg2
модуле, как я начинаю думать, или я делаю что-то действительно неправильное, чтобы получить такой результат?
Ответ №1:
Я не думаю, что это ошибка в Psycopg2 как таковая, поскольку это ограничение, связанное с тем, как rowcount
обрабатывается внутренне. Psycopg2 в основном реализован на C с использованием расширений Python, а тип, который он использует для rowcount, — (signed) long
.
Насколько точно оно велико long
, сильно зависит от среды, в которой оно компилируется. Основываясь на ваших результатах, я подозреваю, что он был скомпилирован в 32-разрядной среде, и поэтому long будет от -2 ^ 31 1 до 2 ^ 31-1.
Вот код на github, где rowcount
он определен: https://github.com/psycopg/psycopg2/blob/56adc590fffbc76fa5e99aa64c657621a630cbe1/psycopg/cursor_type.c
Если бы вы были так склонны, вы могли бы специально скомпилировать его в 64-разрядной среде, чтобы long
он был больше. Смотрите Эту ссылку для установки из источника: http://initd.org/psycopg/docs/install.html#install-from-source
Однако я не уверен, насколько надежным окажется что-то подобное, скомпилированное на заказ.
Моя рекомендация заключалась бы в использовании rowcount
в информационных целях, но не для вещей, требующих безупречной точности. В дополнение к проблемам с переполнением, с которыми вы столкнулись в этом случае, согласно документу, есть и другие случаи, когда -1 будет возвращено в случаях без сбоев. (http://initd.org/psycopg/docs/cursor.html#cursor.rowcount )
Вместо этого, чтобы определить, не завершилась ли операция неудачно (т.Е. Неправильный запрос или Нарушение ограничений FK или аналогичное), ловушка для исключений. Если исключений не было, то операция не завершилась неудачно (хотя она могла обновить / вставить / удалить 0 строк).