Django对象创建和Postgres序列

时间:2010-01-18 18:21:47

标签: django postgresql

我有一个导入脚本,它运行一系列命令,从一个Postgres DB到另一个,从而运行相同的Django代码库。在大多数情况下,它使用./manage.py loaddata进行复制,但有些对象需要额外的处理,我在自定义脚本中使用Django的objects.create()方法来复制数据。这样做时,我指定了ID,即

MyObject.objects.create(id = 2, title = 'foo')

一旦脚本完成,我注意到Postgres SEQUENCE在我执行objects.create()的表上是错误的。即,在导入之前它是50,并且在之后仍然是50,即使该表现在有150个对象。当然,这会在创建新对象时导致错误,因为它会尝试使用已存在的ID(在所有这些表中,ID只是一个vanilla自动增量字段)。但是,通过./manage.py loaddata填充的表似乎没问题。

我知道我可以用Django的./manage.py sqlsequenreset手动重置这些表,但我很好奇为什么序列似乎首先出现了问题。 objects.create()不会增加它吗?我忽略了一些明显的东西吗?

2 个答案:

答案 0 :(得分:12)

一切正常。 django的create()与序列伪造直接无关。简要地:

  • postgresql自动递增 ('serial'类型)只是一个快捷方式 '创建序列+创建整数 序列值为默认值的字段“
  • django的autofield主键(id 如果你没有指定整数,则为整数) 只创建一个串行字段
  • 手动指定id时, postgres将值插入到 数据库。指定值时 它省略了'default'参数, 这是一种正确的行为。

因此,如果您希望插入以您选择的方式递增序列,则需要使用SELECT setval('sequence_name',int_value)手动更改序列值;否则将其保留为空并且它将自动递增 - 选择当前值并将其递增+1(如果在序列定义中没有另外指定)。

另一个想法是你创建对象,然后更新id(当然它不能被使用),最后将序列值设置为最大id。

答案 1 :(得分:2)

自动增量字段有效,但是您必须进行类似

的查询
MyObject.objects.create(title='foo')

没有id字段,这是与数据库自动计算的。