为什么 PostgreSQL 在合并实例时不增加id_sequence last_value?



在之前的问题中,我想知道为什么我在第一次将具有ID的实例合并到数据库(注入夹具数据)时从SA获得完整性错误。

然而,我学会了通过调用我注入的最高索引来解释这个问题:

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

然而,这并没有解决根本的问题,这是我现在正在努力解决的问题。为什么不合并调用nextval()的序列时,插入一个新的行?

如果你的对象已经有了它的PK属性集,那么ID序列将不会被使用,因此不会增加,因为数据库没有理由执行隐式的insert into mytable (id, ...) values ((select nextval from mytable_id_seq), ...)

你确定你需要做一个merge而不是add到你的session ?如果你真的插入,我认为这更像是add操作。如果您只是简单地重用仍然在内存中,但较早添加并且现在可能在数据库中更改的对象,那么merge是合适的。

在我发现这篇文章之前,我一直在与PostgreSQL中的IntegrityErrors问题作斗争。我决定坚持以下规则:如果对象在数据库中不存在,则不要使用db.add()或db.merge()指定主键。

下面是我用来理解berry的意思的例子。

# 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.

最新更新