簡體   English   中英

如何在 Ruby on Rails ActiveRecord 遷移中處理過長的索引名稱?

[英]How do I handle too long index names in a Ruby on Rails ActiveRecord migration?

我正在嘗試添加一個從四個關聯表的外鍵創建的唯一索引:

add_index :studies,
  ["user_id", "university_id", "subject_name_id", "subject_type_id"],
  :unique => true

數據庫對索引名稱的限制導致遷移失敗。 這是錯誤消息:

表 'studies' 上的索引名稱 'index_studies_on_user_id_and_university_id_and_subject_name_id_and_subject_type_id' 太長; 限制為 64 個字符

我該如何處理? 我可以指定不同的索引名稱嗎?

add_index提供:name選項,例如:

add_index :studies,
  ["user_id", "university_id", "subject_name_id", "subject_type_id"], 
  unique: true,
  name: 'my_index'

如果在create_table塊中的references上使用:index選項,它將采用與add_index相同的選項哈希作為其值:

t.references :long_name, index: { name: :my_index }

您還可以更改create_table塊中列定義中的索引名稱(例如您從遷移生成器中獲取)。

create_table :studies do |t|
  t.references :user, index: {:name => "index_my_shorter_name"}
end

在 PostgreSQL 中, 默認限制是 63 個字符 因為索引名稱必須是唯一的,所以有一點約定很好。 我使用(我調整了示例以解釋更復雜的結構):

def change
  add_index :studies, [:professor_id, :user_id], name: :idx_study_professor_user
end

正常的索引應該是:

:index_studies_on_professor_id_and_user_id

邏輯是:

  • index變成idx
  • 單表名
  • 沒有連接詞
  • 沒有_id
  • 按字母順序

這通常可以完成這項工作。

你也可以這樣做

t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')

就像在Ruby on Rails API 中一樣

與上一個答案類似:只需將 'name' 鍵與常規 add_index 行一起使用:

def change
  add_index :studies, :user_id, name: 'my_index'
end

恐怕這些解決方案都不適合我。 也許是因為我在 create_table 遷移中使用了belongs_to來實現多態關聯。

我將在下面添加我的代碼和解決方案的鏈接,以防其他人在搜索與多態關聯相關的“索引名稱太長”時偶然發現。

以下代碼對我不起作用:

def change
  create_table :item_references do |t|
    t.text :item_unique_id
    t.belongs_to :referenceable, polymorphic: true
    t.timestamps
  end
  add_index :item_references, [:referenceable_id, :referenceable_type], name: 'idx_item_refs'
end

這段代碼對我有用:

def change
  create_table :item_references do |t|
    t.text :item_unique_id
    t.belongs_to :referenceable, polymorphic: true, index: { name: 'idx_item_refs' }

    t.timestamps
  end
end

這是幫助我的 SO Q&A: https : //stackoverflow.com/a/30366460/3258059

我有一個經常使用生成器的項目,需要它是自動的,所以我從 rails 源復制了index_name函數來覆蓋它。 我在config/initializers/generated_index_name.rb添加了這個:

# make indexes shorter for postgres
require "active_record/connection_adapters/abstract/schema_statements"
module ActiveRecord
  module ConnectionAdapters # :nodoc:
    module SchemaStatements
      def index_name(table_name, options) #:nodoc:
        if Hash === options
          if options[:column]
            "ix_#{table_name}_on_#{Array(options[:column]) * '__'}".slice(0,63)
          elsif options[:name]
            options[:name]
          else
            raise ArgumentError, "You must specify the index name"
          end
        else
          index_name(table_name, index_name_options(options))
        end
      end
    end
  end
end

它創建像ix_assignments_on_case_id__project_id這樣的索引,如果它仍然太長,則將其截斷為 63 個字符。 如果表名很長,那仍然是不唯一的,但是您可以添加復雜性,例如將表名與列名分開縮短或實際檢查唯一性。

請注意,這是來自 Rails 5.2 項目; 如果您決定這樣做,請從您的版本中復制源代碼。

我有這個問題,但有timestamps功能。 它在 updated_at 上自動生成一個超過 63 個字符限制的索引:

def change
  create_table :toooooooooo_loooooooooooooooooooooooooooooong do |t|
    t.timestamps
  end
end

表 'tooooooooooo_looooooooooooooooooooooooooooong' 上的索引名稱 'index_tooooooooooo_looooooooooooooooooooooooooooooong_on_updated_at' 太長; 限制為 63 個字符

我嘗試使用timestamps來指定索引名稱:

def change
  create_table :toooooooooo_loooooooooooooooooooooooooooooong do |t|
    t.timestamps index: { name: 'too_loooooooooooooooooooooooooooooong_updated_at' }
  end
end

但是,這會嘗試將索引名稱應用於updated_atcreated_at字段:

表 'toooooooooo_looooooooooooooooooooooooooooooong' 上的索引名稱 'too_long_updated_at' 已經存在

最后我放棄了timestamps ,只是創建了很長的時間戳:

def change
  create_table :toooooooooo_loooooooooooooooooooooooooooooong do |t|
    t.datetime :updated_at, index: { name: 'too_long_on_updated_at' }
    t.datetime :created_at, index: { name: 'too_long_on_created_at' }
  end
end

這有效,但我很想知道是否可以使用timestamps方法!

create_table :you_table_name 做 |t| t.references :studant, index: { name: 'name_for_studant_index' } t.references :teacher, index: { name: 'name_for_teacher_index' } end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM