Deviseと気の利いたジェネレーターでデータベースを作成しました。私は気の利いたジェネレーターで新しいデータベースを作成しようとしています(Rails g nifty:scaffold Asset user_id:integer
)が、データベースを移行しようとすると(rake db:migrate
)、次のエラーが表示されます。
charlotte-dator:showwwdown holgersindbaek$ rake db:migrate
== DeviseCreateUsers: migrating ==============================================
-- create_table(:users)
rake aborted!
An error has occurred, all later migrations canceled:
Mysql2::Error: Table 'users' already exists: CREATE TABLE `users` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `email` varchar(255) DEFAULT '' NOT NULL, `encrypted_password` varchar(128) DEFAULT '' NOT NULL, `reset_password_token` varchar(255), `reset_password_sent_at` datetime, `remember_created_at` datetime, `sign_in_count` int(11) DEFAULT 0, `current_sign_in_at` datetime, `last_sign_in_at` datetime, `current_sign_in_ip` varchar(255), `last_sign_in_ip` varchar(255), `name` varchar(255), `created_at` datetime, `updated_at` datetime) ENGINE=InnoDB
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
私はチュートリアルに従っていますが、これがなぜ起こるのかを理解するのにかなり苦労しています。誰が何が起こっているのか説明できますか?
移行は、データベースに既に存在するテーブルを作成しようとしています。
データベースからユーザーテーブルを削除してください。移行プロセスで問題が発生しました。また、schema.rbのバージョンとdb/migrate/*。rbファイルを比較する必要があります。
明確化:
多くのSOユーザーは、返信が不正確であるか推奨されていないため、私の返信に同意しないようです。
テーブルの削除は常に破壊的であり、誰もがそれを理解していると思います。
テーブルは別の移行ファイルで作成されていたため、 add_column に言及する必要がありました。
create_users
移行(APP_ROOT/db/migrate/..)で、drop_table :users
の直前にcreate_table :users
を追加し、rake db:migrate
を実行します。再作成する前にusersテーブルを削除します。この移行を実行した後、そのコード行を削除して、後でエラーが発生しないようにすることができます。データベースへのUIアクセスがない場合(Herokuなど)の小さな修正。
そのテーブルをsql liteコンソールから削除する必要があります(含まれるすべてのデータが失われます)。
Sql liteコンソールにアクセスし、ターミナルに入力しますmysql <DB NAME HERE>
テーブルの削除(最後の;(セミコロン)を忘れないでください)drop table table_name;
db:migrateを再度実行しますbin/rake db:migrate
役に立てば幸いです
安全にプレイしてデータを失いたくない場合は、データベースにテーブルが存在するかどうかを確認できます。
class DeviseCreateUsers < ActiveRecord::Migration
def up
if table_exists?(:users)
# update or modify columns of users table here accordingly.
else
# create table and dump the schema here
end
end
def down
# same approach goes here but in the reverse logic
end
end
データベースが適切に作成されたことがわかっている場合は、移行コードの作成部分をコメントアウトするだけです。例えば:
Class ActsAsVotableMigration < ActiveRecord::Migration
def self.up
# create_table :votes do |t|
#
# t.references :votable, :polymorphic => true
# t.references :voter, :polymorphic => true
#
# t.boolean :vote_flag
#
# t.timestamps
# end
#
# add_index :votes, [:votable_id, :votable_type]
# add_index :votes, [:voter_id, :voter_type]
end
def self.down
drop_table :votes
end
end
テーブルは作成されたが、何らかの理由で後のコマンドが完了しなかった場合は、後のオプションをそのままにしておくことができます。例:
Class ActsAsVotableMigration < ActiveRecord::Migration
def self.up
# create_table :votes do |t|
#
# t.references :votable, :polymorphic => true
# t.references :voter, :polymorphic => true
#
# t.boolean :vote_flag
#
# t.timestamps
# end
add_index :votes, [:votable_id, :votable_type]
add_index :votes, [:voter_id, :voter_type]
end
def self.down
drop_table :votes
end
end
ただし、データベースに重要なデータが保存されていない場合は、テーブルとすべてのデータを削除して、新しいデータを作成するだけで済みます。例えば(self.upの "drop_table:votes"に注意してください):
class ActsAsVotableMigration < ActiveRecord::Migration
def self.up
drop_table :votes
create_table :votes do |t|
t.references :votable, :polymorphic => true
t.references :voter, :polymorphic => true
t.boolean :vote_flag
t.timestamps
end
add_index :votes, [:votable_id, :votable_type]
add_index :votes, [:voter_id, :voter_type]
end
def self.down
drop_table :votes
end
end
テーブルを削除しないでください。データ>移行!
データベースのバージョンは、エラーの原因となる移行が追加しようとしている変更をすでに反映しています。つまり、移行をスキップできれば、すべて問題ありません。 db_schema_migrationsテーブルを確認し、誤った移行のバージョンを挿入してみてください(例:20151004034808)。私の場合、これにより後続の移行が完全に実行され、すべてが正常に思えます。
この問題の原因はまだわかりません。
既存のユーザーテーブルにDevise認証を追加しようとすると、同様の問題が発生しました。
私の解決策:2つの移行ファイルがあり、どちらもUsersテーブルを作成しようとしていることがわかりました。したがって、テーブルを削除するのではなく(おそらく形成するのが最良の習慣ではありません)、Usersテーブルを作成した最初の(元の)移行ファイルをコメントアウトし、Devise移行ファイルをそのまま残しました。移行を再実行し、正常に機能しました。
結局のところ、Deviseファイルは問題を引き起こしていませんでした。テーブルを「作成」するのではなく、「変更」することがわかります。つまり、デバイスをインストールしなくても、db:migrateで同じ問題が発生する可能性があります(これはテストしていません)。
データを保持する、テーブルの名前を変更するで、時間を節約するために移行で行う場合は、移行が実行されたら削除します。
移行ファイルのpセクションの上部に配置します。
rename_table :users, :users2
これはRailsのmysqlに固有の問題またはより一般的な問題であり、mysql2 gem自体に関係している可能性があります。
これは、sqliteからmysqlに切り替えたばかりで、この問題が体系的に発生し始めたためです。
私の場合、すでに実行されていたコードをコメントアウトし、移行を再度実行しました(私の上の男がそうしたように見えるので、詳細は追加しません)。
アプリが新しく、データベース内のデータを気にしない場合は、次のようにします。
rake db:reset