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

时间:2011-08-12 18:54:58

标签: python postgresql sqlalchemy

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

但是,我通过调用我注入的最高索引来学习解决问题:

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

但是,这并没有解决潜在的问题,这就是我现在正在努力解决的问题。为什么在插入新行时不合并对序列调用nextval()?

2 个答案:

答案 0 :(得分:3)

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

您确定需要对merge进行add而不是session吗?如果你真的插入,我认为这更像是add操作。如果您只是重新使用仍在内存中但之前添加并且可能现在在数据库中更改的对象,那么merge是合适的。

答案 1 :(得分:0)

我在PostgreSQL中遇到同样的IntegrityErrors问题,直到找到这篇文章。我决定坚持以下规则:如果数据库中不存在该对象,请不要使用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.