2

本番データベースにロードしようとしているシードデータを含むXMLファイルがあります。

問題は、XMLファイル内の異なるデータ型/ノード間に関連付けがあるため、RailsからMySQLにロードするときに指定したIDが同じである必要があることです。

これは開発中のSQLiteで正常に機能します。XMLファイルの各ノードを反復処理した後、次のような行を使用します。

CardSet.connection.execute("UPDATE card_sets SET id = #{xml_set.attributes['id']} WHERE id = #{set.id}")

私の質問は、データベースをシードするときに事前設定されたIDを強制し、Railsが通常どおり機能するようにauto_incrementをオンに戻すにはどうすればよいですか?

データベースエントリを作成する前に、次の2行でこれを試みました。

CardSet.connection.execute("ALTER TABLE card_sets CHANGE id id INT(11) DEFAULT NULL")
CardSet.connection.execute("ALTER TABLE card_sets DROP PRIMARY KEY")

そしてこの後:

CardSet.connection.execute("ALTER TABLE card_sets CHANGE id id INT(11) DEFAULT NULL auto_increment PRIMARY KEY")

MySQLは次のように私に反撃します:

Mysql::Error: ALTER TABLE causes auto_increment resequencing, resulting in duplicate entry '18' for key 'PRIMARY': ALTER TABLE card_sets CHANGE id id INT(11) DEFAULT NULL auto_increment PRIMARY KEY

私のスキーマ:

create_table "card_sets", :force => true do |t|
  t.string   "name"
  t.datetime "created_at"
  t.datetime "updated_at"
end

create_table "card_sets_cards", :id => false, :force => true do |t|
  t.integer "card_set_id"
  t.integer "card_id"
end

create_table "cards", :force => true do |t|
  t.text     "question",   :default => ""
  t.text     "answer",     :default => ""
  t.datetime "created_at"
  t.datetime "updated_at"
end

そしてモデル:

class CardSet < ActiveRecord::Base
  has_and_belongs_to_many :cards, :uniq => true
end

class Card < ActiveRecord::Base
    has_and_belongs_to_many :card_set, :uniq => true
end

任意のアイデアをいただければ幸いです。

4

2 に答える 2

5

MySQLエラーを回避する方法は、モデルインスタンスを通常どおりに作成し(CardSet.create)、IDを強制的に更新してから、インスタンスをリロードすることでした。

c = CardSet.create(...blah....)
CardSet.connection.execute("UPDATE card_sets SET id = #{real_card_set_id} WHERE id = #{c.id}")
c = CardSet.find(real_card_set_id)
c.save!
于 2010-07-30T02:02:21.787 に答える
4

オブジェクトをブロック形式で作成すると、機能します。

p = Post.new do |post|
  post.id = 1000
end

p.save
于 2010-05-05T14:52:06.113 に答える