Rails db:migrate error, index is too long

问题发现

今天在跑migrate,代码如下:

class CreateReconciliationOrderItems < ActiveRecord::Migration[5.1]
  def change
    create_table :reconciliation_order_items do |t|
      t.string  :kind
      t.string  :month
      t.text    :content
      t.string  :status
      t.string  :type
      t.references :reconciliation
      t.references :reconciliation_result_set
      t.string  :internal_source_type
      t.string  :internal_source_id
      t.timestamps null: false
    end
  end
end

数据库报了一个错误:

   (0.3ms)  SELECT pg_try_advisory_lock(5675054488983918780)
   (1.4ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
Migrating to CreateReconciliationOrderItems (20180116061824)
   (0.2ms)  BEGIN
== 20180116061824 CreateReconciliationOrderItems: migrating ===================
-- create_table(:reconciliation_order_items)
   (21.0ms)  CREATE TABLE "reconciliation_order_items" ("id" bigserial primary key, "kind" character varying, "month" character varying, "content" text, "status" character varying, "type" character varying, "reconciliation_id" bigint, "reconciliation_result_set_id" bigint, "internal_source_type" character varying, "internal_source_id" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
   (1.0ms)  CREATE  INDEX  "index_reconciliation_order_items_on_reconciliation_id" ON "reconciliation_order_items"  ("reconciliation_id")
   (1.6ms)  ROLLBACK
   (0.3ms)  SELECT pg_advisory_unlock(5675054488983918780)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

Index name 'index_reconciliation_order_items_on_reconciliation_result_set_id' on table 'reconciliation_order_items' is too long; the limit is 63 characters

重点是在最后一句

Index name 'index_reconciliation_order_items_on_reconciliation_result_set_id' on table 'reconciliation_order_items' is too long; the limit is 63 characters

刚开始我并不知道这个问题的所在。只当是版本上周升级rails5的遗留问题,并且这个migrate在线上环境已经跑过了,问题不是特别大,也就每当回事。等闲下来之后查了一下资料,网上又很完善的介绍。

pg数据库文档中有说:

The system uses no more than NAMEDATALEN-1 bytes of an identifier; longer names can be written in commands, but they will be truncated. By default, NAMEDATALEN is 64 so the maximum identifier length is 63 bytes. If this limit is problematic, it can be raised by changing the NAMEDATALEN constant in src/include/pg_config_manual.h.

大概意思就是SQL标识符与关键字不能超过64个字节。因此,我们只能创建64-1个字节,也就是63个字节。为此,rails中有相应指明name的方法。
代码如下

t.references :reconciliation_result_set, index: { name: 'index_on_reconciliation_result_set_id'}

你可以在migrate中直接声明name的名字,也可以使用

add_index :reconciliation_order_items, : reconciliation_result_set_id, name: 'index_on_reconciliation_result_set_id'

就是不使用默认的声明名称,自定义符合要求的声明名称即可。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,833评论 19 139
  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 32,162评论 2 89
  • 世界上总有那么一些人,喜欢打着我为你好的幌子,胡乱揣测别人的生活。 在他们看来,自己的行为写着满满的善意,闪闪发光...
    Su木溪阅读 4,685评论 2 6
  • 为闺蜜宝宝在用着并且代理了,我也就顺带的开着淘宝店开始卖尿不湿了,淘宝店开业之后,一直没有用心去打理,直到近日陆陆...
    珍眼看世界阅读 681评论 0 0
  • 近日,很多地区都进入了可以在马路上摊鸡蛋的高温季节了,相比较古代,现代有了空调,电扇等预防高温的杀手锏,不知道幸福...
    保健头条阅读 2,435评论 2 1

友情链接更多精彩内容