获取DatabaseError:为列指定了多个默认值

时间:2014-05-07 20:26:40

标签: sql postgresql django-south askbot

每当我尝试在我的一个Django项目中使用South进行迁移时,我无法弄清楚如何避免此错误:

ERROR:

为askbot运行迁移:

  
      
  • 向前迁移到0006_auto__del_field_tagplus_tag_ptr__add_field_tagplus_id__add_field_tagpl。
  •   
     

askbot:0006_auto__del_field_tagplus_tag_ptr__add_field_tagplus_id__add_field_tagpl

     

致命错误 - 以下SQL查询失败:ALTER TABLE“tagplus”ADD COLUMN“id”serial NOT> NULL PRIMARY KEY DEFAULT -1;   错误是:为表“tagplus”的列“id”指定了多个默认值

     

迁移错误:> askbot:0006_auto__del_field_tagplus_tag_ptr__add_field_tagplus_id__add_field_tagpl    DatabaseError:为表“tagplus”

的列“id”指定了多个默认值

移民文件0006代码(部分):

class Migration(SchemaMigration):

def forwards(self, orm):
    # Deleting field 'TagPlus.tag_ptr'
    db.delete_column(u'tagplus', u'tag_ptr_id')

    # Adding field 'TagPlus.id'
    db.add_column(u'tagplus', u'id',
                  self.gf('django.db.models.fields.AutoField')(default=0, primary_key=True),
                  keep_default=False)

    # Adding field 'TagPlus.name'
    db.add_column(u'tagplus', 'name',
                  self.gf('django.db.models.fields.CharField')(default=0, unique=True, max_length=255),
                  keep_default=False)

谢谢!

编辑:

我猜这个错误与我在创建迁移文件时提示的选择有关。

 ? The field 'TagPlus.tag_ptr' does not have a default specified, yet is NOT NULL.
 ? Since you are removing this field, you MUST specify a default
 ? value to use for existing rows. Would you like to:
 ?  1. Quit now.
 ?  2. Specify a one-off value to use for existing columns now
 ?  3. Disable the backwards migration by raising an exception; you can edit the migration to fix it later
 ? Please select a choice: 

我选择了“指定一次性值”并将此值设置为0

2 个答案:

答案 0 :(得分:3)

你总是说keep_default=False。因此,请从代码中删除default=0

   db.add_column(u'tagplus', u'id',
                  self.gf('django.db.models.fields.AutoField')(primary_key=True),
                  keep_default=False)

每个SQL应该是(删除NOT NULL

ALTER TABLE tagplus ADD COLUMN id serial PRIMARY KEY

请参阅此文档,该文档解释了此错误http://www.postgresql.org/docs/8.3/interactive/datatype-numeric.html#DATATYPE-SERIAL

背后的原因

答案 1 :(得分:2)

有两点需要注意:

  1. Django将使用' id'如果您之前未手动设置,请参阅默认主键,请参阅here

  2. Postgres真的没有'序列'类型。要解决此问题,请尝试替换:

    # Adding field 'TagPlus.id'
    db.add_column(u'tagplus', u'id', self.gf('django.db.models.fields.AutoField')(default=0, primary_key=True), keep_default=False)
    
  3. 使用:

        # Adding field 'TagPlus.id'
        if 'postgres' in db.backend_name.lower():
            db.execute("CREATE SEQUENCE tagplus_id_seq")
            db.execute("SELECT setval('tagplus_id_seq', (SELECT MAX(id) FROM tagplus))")
            db.execute("ALTER TABLE tagplus ADD COLUMN id SET DEFAULT nextval('tagplus_id_seq'::regclass)")
            db.execute("ALTER SEQUENCE tagplus_id_seq OWNED BY tagplus.id")
        else:
            db.add_column(u'tagplus', u'id', self.gf('django.db.models.fields.AutoField')(default=0, primary_key=True), keep_default=False)