【问题标题】:Restore primary key in active record schema恢复活动记录模式中的主键
【发布时间】:2013-04-03 21:34:48
【问题描述】:

不知何故,我的架构以这个 id 列结束:

create_table "tables", :id => false, :force => true do |t|
    t.integer  "id",                                         :null => false
    # other fieds
  end

这是列上的信息(注意主要是假的):

[4] pry(main)> Table.columns.first
=> #<ActiveRecord::ConnectionAdapters::PostgreSQLColumn:0x007f98d06cc0f8
 @coder=nil,
 @default=nil,
 @limit=nil,
 @name="id",
 @null=false,
 @precision=nil,
 @primary=false,
 @scale=nil,
 @sql_type="integer",
 @type=:integer>

所以每当我尝试保存新记录时都会出现此错误: ActiveRecord::StatementInvalid: PG::Error: ERROR: null value in column "id" violates not-null constraint

恢复主键的最佳方法是什么?

【问题讨论】:

  • 你能详细解释一下这是怎么发生的吗?您创建了一个没有id 的表,然后想要添加一个?
  • 我不知道它是怎么发生的。我查看了迁移,它没有明确设置此表的 id 字段。
  • 现在要删除它吗?
  • 另外,您可能想重新考虑使用表名tables,因为它可能在 postgres 的保留关键字中。也许有更多经验的人会对此多说一些
  • “tables”这个名字只是这个问题的假名。

标签: ruby-on-rails ruby-on-rails-3 activerecord


【解决方案1】:

Rails 迁移本身无法处理此问题 - 您需要将 execute 与设置主键的 SQL 一起使用,创建缺少的序列,将序列移动到最新的 'id' 值(如果存在) ),并将序列 nextval 指定为默认值:

execute("ALTER TABLE tables ADD PRIMARY KEY (id);")
execute("CREATE sequence tables_id_seq;")

# skip this next line if you know that no rows exist yet
execute("SELECT setval('tables_id_seq', (SELECT MAX(id) FROM tables));")    

execute("ALTER TABLE tables ALTER id SET DEFAULT nextval('tables_id_seq');")

【讨论】:

  • 当。它说 PG::Error: ERROR: 关系“tables_id_seq”已经存在。
  • @DavidNix:啊哈,所以它一定是一个主键。在这种情况下,只需跳过第二行 execute("CREATE sequence...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多