Получение количества строк, превышающих MAX_INT, из курсора в psycopg2 Python с помощью Amazon Redshift

#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 строк).