oro*_*aki 41 postgresql constraint primary-key postgresql-9.2
我正在使用 Django,但每隔一段时间我就会收到此错误:
IntegrityError:重复键值违反唯一约束“myapp_mymodel_pkey”
详细信息:键(id)=(1)已经存在。
我的 Postgres 数据库实际上有一个主键为 1的myapp_mymodel对象。
为什么 Postgres 会尝试再次使用该主键?或者,这很可能是我的应用程序(或 Django 的 ORM)导致的吗?
刚才这个问题又连续出现了3次。我发现,当它确实发生时,对于给定的表,它会连续发生一次或多次,然后不会再次发生。它似乎在每张桌子完全停止数天之前发生,当它确实发生时每张桌子至少发生一分钟左右,并且只是间歇性地发生(不是所有桌子都立即发生)。
这个错误是如此间歇性的(在 2 周内仅发生 3 次左右 - 数据库上没有其他负载,只是我测试了我的应用程序)这一事实让我对低级问题如此警惕。
dez*_*zso 52
PostgreSQL 不会尝试自行插入重复值,而是您(您的应用程序,包括 ORM)会这样做。
它可以是一个序列,将值提供给设置为错误位置的 PK 并且表已经包含等于它的值nextval()- 或者只是您的应用程序做了错误的事情。第一个很容易修复:
SELECT setval('your_sequence_name', (SELECT max(id) FROM your_table));
Run Code Online (Sandbox Code Playgroud)
第二个是调试。
Django(或任何其他流行的框架)不会自行重置序列 - 否则我们每隔一天就会遇到类似的问题。
小智 14
您最有可能在未更新序列列序列值的表中插入一行。
考虑表中的以下列,它是 Django ORM 为 postgres 定义的主键
id serial NOT NULL
Run Code Online (Sandbox Code Playgroud)
其默认值设置为
nextval('table_name_id_seq'::regclass)
Run Code Online (Sandbox Code Playgroud)
仅当 id 字段设置为空白时才会评估序列。但是如果表中已经有条目,那就是问题了。
问题是为什么那些较早的条目没有触发序列更新?那是因为 id 值是为所有较早的条目明确提供的。
在我的情况下,这些初始条目是通过迁移从装置加载的。
通过具有随机 PK 值的自定义条目,此问题也可能变得棘手。
说例如。您的表中有 10 个条目。您使用 PK=15 进行显式输入。通过代码接下来的四个插入可以正常工作,但第 5 个会引发异常。
DETAIL: Key (id)=(15) already exists.
Run Code Online (Sandbox Code Playgroud)