Как в SQL обновить таблицу, установив в столбце другое значение для каждой строки?
Я хочу обновить некоторые строки в базе данных PostgreSQL, установив для одного столбца число из последовательности, где этот столбец имеет уникальное ограничение. Я надеялся, что смогу просто использовать:
update person set unique_number = (select nextval('number_sequence') );
но кажется, что nextval вызывается только один раз, поэтому при обновлении используется один и тот же номер для каждой строки, и я получаю ошибку «повторяющийся ключ нарушает уникальное ограничение». Что мне делать вместо этого?


Не используйте подзапрос, а используйте функцию nextval напрямую, например:
update person set unique_number = nextval('number_sequence');
Если вы хотите повторно использовать то же значение последовательности после вызова nextval ('sequence'), вы можете использовать связанную функцию currval ('sequence'), которая возвращает текущую последовательность.
Я считаю последовательности pg уловкой и признаком того, что инкрементные целые числа - не лучший способ создания ключей. Хотя в pgsql не было встроенной поддержки UUID до версии 8.3.
http://www.postgresql.org/docs/8.3/interactive/datatype-uuid.html
Преимущества UUID в том, что комбинации почти бесконечны, в отличие от случайного числа, которое однажды столкнется с конфликтом.
"Почти бесконечно?" Документы говорят, что это 128-битный целочисленный тип. Это много, но не бесконечно, и почти наверняка произойдет конфликт до того, как будут использованы все значения 2 ^ 128. Кроме того, ORM, вероятно, придется преобразовывать в строковые типы и из них, чтобы использовать это. На мой взгляд, непонятная победа.
Я думаю, вы недооцениваете размер 2 ^ 128, почитайте о uuid в Википедии.
Это в основном академическое, но последовательность Postgres может быть более защищенной от конфликтов, чем UUID, в зависимости от того, как она создана. Модуль uuid Python использует случайный компонент, но существенно меньше 128 случайных битов. Последовательности сталкиваются только в том случае, если они циклически повторяются, случайные числа сталкиваются ... случайным образом.
У Postgres есть собственный генератор uuid, которого я не видел, но он вполне может быть лучше, чем у Python, fwiw.
Спасибо, работает. Меня поймал подвыбор, потому что я пытался использовать один и тот же порядковый номер для двух столбцов, но мне это действительно не нужно.