Mysql2::Error:只能有一个自动列,并且必须将其定义为键

Posted

技术标签:

【中文标题】Mysql2::Error:只能有一个自动列,并且必须将其定义为键【英文标题】:Mysql2::Error: there can be only one auto column and it must be defined as a key 【发布时间】:2019-05-23 22:49:12 【问题描述】:

尝试启动并运行 rails 应用程序。我从同事以 schema.rb 给出的下表定义中收到此错误。

ActiveRecord::StatementInvalid: mysql2::Error: Incorrect table definition; there can be only one auto column and it must be defined as a key 

表定义:

  create_table "wv latest", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
    t.integer "id", null: false, auto_increment: true
    t.string "cid", limit: 10
    t.integer "visit_id"
    t.string "cfname", limit: 20
    t.string "clname", limit: 25
  end

当我删除时

auto_increment: true

错误消失了。为什么会发生这种情况?为什么架构在我的设置中不起作用?

【问题讨论】:

create_table 有点奇怪。你有id: false(即不自动创建一个自动递增的id 列作为PK),但它几乎创建了id: false 阻止Rails 自己创建的东西。这些表是否来自其他应用程序? 是的,我想。我刚刚开始这份工作,我很确定那里有近 20 年的遗留数据。哈哈。好玩好玩。 如果是这样(我不怀疑),我想知道您是否会更好地使用structure.sql instead of schema.rb。如果有历史并且 Rails 是历史中的另一层,那么使用 MySQL 的原始模式转储可能比试图将东西硬塞到 Rails 中更好。 我可以调查一下。问题是已经有一个 Rails 应用程序连接到这个数据库,这就是我从中获取 schema.rb 的地方。我只是想如果它适用于该应用程序,它应该适用于我的。大多数东西都是等价的,rails 版本,mysql 版本。但也许 schema.rb 和数据库的实际模式在某处不同步。 【参考方案1】:

错误消息告诉您只有列可以自动递增,并且该列也必须是主键。因此,尝试将 id 列设为主键:

create_table "wv latest", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
    t.integer "id", null: false, auto_increment: true, primary_key: true
    t.string "cid", limit: 10
    t.integer "visit_id"
    t.string "cfname", limit: 20
    t.string "clname", limit: 25
end

【讨论】:

我已经确认,如果我删除 auto_increment 或者按照您的建议添加 primary_key: true,架构将会加载。就我而言,这个问题是我正在尝试连接一个新应用程序以共享另一个 Rails 应用程序的数据库。我不得不要求所有者将其添加到他们的数据库中。只是不知道为什么它对我不起作用,但对他们有用。 这可能是由于多种原因。在我的脑海中,您的 MySQL 版本/配置可能会有所不同。从设计的角度来看,执行这一点并没有错。

以上是关于Mysql2::Error:只能有一个自动列,并且必须将其定义为键的主要内容,如果未能解决你的问题,请参考以下文章

Phpmyadmin #1075 - 表定义不正确;只能有一个自动列,并且必须将其定义为键

SQLSTATE[42000]:语法错误或访问冲突:1075 表定义不正确;只能有一个自动列,并且必须将其定义为键

从 Mysql2::Error 中救援

Rails db:schema:load 错误:Mysql2::Error:无法删除或更新父行:外键约束失败

Mysql2::Error: 不正确的字符串值

长时间任务后,ActiveRecord 在简单更新期间抛出 Mysql2::Error::ConnectionError