Почему PostgreSQL не увеличивает last_value для id_sequence при объединении экземпляра? - PullRequest
1 голос
/ 12 августа 2011

В предыдущем вопросе мне было интересно, почему я получаю сообщение об ошибке целостности от SA при первом объединении экземпляра с идентификатором в базу данных (ввод данных фиксатора).

Однако я научился объяснять проблему, звоня с наивысшим индексом, который я ввожу:

select setval('my_items_id_seq', {id});

Однако это не решило основную проблему, с которой я сейчас борюсь. Почему не слить вызов nextval () в последовательности при вставке новой строки?

Ответы [ 2 ]

3 голосов
/ 13 августа 2011

Если для вашего объекта уже установлен атрибут PK, последовательность идентификаторов не будет использоваться и, следовательно, не будет увеличена, поскольку у базы данных нет причин для выполнения неявного insert into mytable (id, ...) values ((select nextval from mytable_id_seq), ...).

Вы уверены, что вам нужно сделать merge вместо add для вашего session? Если вы действительно вставляете, я бы подумал, что это скорее операция add. Если вы просто повторно используете объект, который все еще находится в памяти, но добавлен ранее и, возможно, теперь изменен в базе данных, тогда merge подходит.

0 голосов
/ 24 сентября 2011

Я боролся с той же проблемой IntegrityErrors в PostgreSQL, пока не нашел этот пост.Я решил придерживаться следующего правила: , если объект не существует в базе данных, НЕ указывайте первичный ключ с помощью db.add () или db.merge ().

Вот примеры, которые я использовал, чтобы понять, что имел в виду wberry.

# Suppose the next value of rows_id_seq will be 33.
# You run the following code.
db.add(Row(id=35))
# Since you specified a primary key, SQLAlchemy will NOT increment rows_id_seq,
# so the next value of rows_id_seq will still be 33.
db.add(Row())
# The next value of rows_id_seq will be 34
db.add(Row())
# The next value of rows_id_seq will be 35
db.add(Row())
db.query(Row.id).all() # Uh-oh
# (IntegrityError) duplicate key value violates unique constraint "rows_pkey"
# Key (id)=(35) already exists.

Вот пример использования db.merge () .

# Suppose the next value of rows_id_seq will be 1.
# You run the following code.
db.merge(Row(id=1))
db.merge(Row(id=2))
db.merge(Row(id=3))
# Since you specified a primary key, SQLAlchemy will NOT increment rows_id_seq,
# so the next value of rows_id_seq will still be 1.
db.merge(Row())
db.query(Row.id).all() # Uh-oh
# (IntegrityError) duplicate key value violates unique constraint "rows_pkey"
# Key (id)=(1) already exists.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...