Rake aborted... table 'users' already exists - ruby-on-rails

I have created a database with devise and the nifty generator. I'm trying to make a new database with the nifty generator (rails g nifty:scaffold Asset user_id:integer), but when I try to migrate the database (rake db:migrate), I get the following error:
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)
I'm following a tutorial and have quite a hard time understanding why this happens. Can anyone explain what is going on?

In your create_users migration (APP_ROOT/db/migrate/..), add drop_table :users right before create_table :users and run rake db:migrate. It will remove the users table before recreating it. You can remove that line of code after running this migration so it doesn't give you errors later on. Just a small fix if you dont have UI access to a database (on heroku, for example).

You need to drop that table from the sql lite console (You will lost all the data contained in it)
Access the sql lite console, type in terminal
mysql <DB NAME HERE>
Drop table (dont forget the last ; (semicolon))
drop table table_name;
run db:migrate again
bin/rake db:migrate
Hope it helps, it worked for me

If you wanna play safe and don't want to lose any data then you can check if the table exists in your database.
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

The migration is trying to create a table that already exists in your database.
Try to remove the user table from your database. Something went wrong with you migration process. You should also compare your schema.rb version with your db/migrate/*.rb files.
Clarification:
It seems that many SO users don't agree with my reply, either because they consider it inaccurate or not recommended.
Removing a table is always destructive, and I think that everyone understands that.
I should have mentioned add_column, since the table was being created in another migration file.

If you know the database was created properly, you can just comment out the creation part of the migration code. For example:
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
If the table was created, but later commands weren't completed for some reason, you can just leave the later options for example:
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
If you don't have any significant data in your database to preserve however you can just have it drop the table and all the data and create it fresh. For example (notice the "drop_table :votes", in the self.up):
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

Don't delete tables. Data > migrations!
The version of the database already reflects the changes the error-causing migration is trying to add. In other words, if the migration could be skipped, then everything would be fine. Check the db_schema_migrations table and try inserting the version of the erroneous migration (e.x, 20151004034808). In my case this caused subsequent migrations to execute perfectly and everything seems fine.
Still not sure what caused this problem.

If your app is new and you don't care about the data in your database, simply:
rake db:reset

I think this is an issue unique or more common to mysql in rails, possible having to do with the mysql2 gem itself.
I know this because I just switched from sqlite to mysql and just started having this problem systematically.
In my case, I simply commented out the code that had already run and ran the migration again (which I'm not adding more detail to because it looks like the guy above me did that).

I had a similar problem when trying to add Devise authentication to an existing Users table.
My solution: I found that I had two migrate files, both trying to create the Users table. So rather than deleting the table (probably not the best habit to form), I commented out the first (original) migrate file that created the Users table and then left the Devise migrate file as-is. Re-ran the migration and it worked fine.
As it turns out, the Devise file wasn't causing the problem; I can see that it is "changing" the table, not "creating it", which means that even without the devise installation, a db:migrate probably would have caused the same issue (though I haven't tested this).

If you want to keep your data, rename the table, but do it in the migration to save time, then remove it once the migration has ran.
Place at the top part of the up section of the migration file.
rename_table :users, :users2

Related

Rails error: Index name '...' on table '...' already exists while running rails db:migrate

So I'm working with a colleague who added some additional migration files and per normal procedure once I pulled their version I ran rails db:migrate. I end up getting the following errors:
Index name 'index_authorizations_on_user_id' on table 'authorizations' already exists
ArgumentError: Index name 'index_authorizations_on_user_id' on table 'authorizations' already exists
So I went and checked the schema and the table is already present. So why is it failing? Typically in the past it only generates new table entries/updates when doing a migration so why isn't it just ignoring it?
I've tried doing a rollback and get:
This migration uses remove_columns, which is not automatically reversible.
I've tried doing bin/rails db:migrate RAILS_ENV=development and I get the same errors.
I've done a db:reset, db:drop, and it all comes back to an issue with pending migrations that I cannot get to run. What am I doing wrong?
They added the following migration: 20171024074328_create_authorizations.rb
class CreateAuthorizations < ActiveRecord::Migration[5.1]
def change
create_table :authorizations do |t|
t.string :provider
t.string :uid
t.references :user, foreign_key: true
t.timestamps
add_index :authorizations, :user_id
add_index :authorizations, [:provider, :uid], unique: true
end
end
end
This:
t.references :user, foreign_key: true
adds an index on authorizations.user_id for you. If you check the references documentation it will point you at add_reference and that says:
:index
Add an appropriate index. Defaults to true. [...]
So index: true is the default when you call t.references :user and that creates the same index that add_index :authorizations, :user_id creates.
So the only thing that I've found that "worked" was to actually delete the migration files then run rails db:migrate. Didn't catch on anything, no errors.
Not a fan of the fact that this worked.
Check if it's a table or a changed table, most times you need to drop the table or delete the column then run the migration again and it'll be good to go

Missing table column, defined in migrate

I tried to create a new Link table and specified the necessary columns under migration.
under db/migrate
class CreateLinks < ActiveRecord::Migration
def change
create_table :links do |t|
t.integer :user_id
t.string :url
t.timestamps
end
end
end
class AddTitleToLink < ActiveRecord::Migration
def change
# add_column :links, :user_id, :integer
add_column :links, :title, :string
end
end
When I ran rails console, Link returned
Link(id: integer, created_at: datetime, updated_at: datetime, title: string)
It seems like user_id (the foreign key) and url are missing. Title, which was added later, is in the table.
Did I do anything wrong?
Did you perhaps run the CreateLinks migration before editing it to add the two fields? If so, you can change that file all day long and rake db:migrate will never re-run it. That would explain there being an empty table links, and the field you then added to it in the next migration.
You can step the database back by running rake db:rollback. Try doing that twice, then migrate again.
Can't see any reason for this not to work. Is it possible that you first ran:
rails g model Link
(which generated a migration AND RAN it)
and then you manually added the :url and :user_id?
Try running twice:
rake db:rollback
Then run again
rake db:migrate
which will catch up your manual modifications

Ruby on rails How to remove added columns and insert new columns through a migration file

HI I created a Ruby on rails migration file as follows and in the first stage I created tables
then I want to add columns and remove some columns and I modified it as follows
class CreateMt940Batches < ActiveRecord::Migration
def change
create_table :mt940_batches do |t|
t.string :account_number
t.string :transaction_reference_number
t.string :information_to_account_owner
t.string :file_name
t.binary :raw_data_transaction
t.string :sha1_checksum
t.timestamps
end
def self.down
remove_column :account_number, :transaction_reference_number, :information_to_account_owner
end
def self.up
add_column :mt940_batches, :created_by, :updated_by, :integer
end
end
end
but when I ran rake db:migrate nothing has happens. How to accomplish this task . I want to change the model already created as well from this migration file. Um looking a way to do this. Thank you in advance
You should add your remove / add column in a separate migration file.
class FooMigration < ActiveRecord::Migration
def down
remove_column :account_number, :transaction_reference_number, :information_to_account_owner
end
def up
add_column :mt940_batches, :created_by, :updated_by, :integer
end
end
Please note that your up and down method should be idem potent. You should be able to go from one to the other when calling rake db:migrate:down and rake db:migrate:up. This is not the case here.
However here, it seems that you want to achieve 2 different things in a single migration. If you want to add AND remove columns, consider moving each one in a different migration file:
Please read here for more details
You would end up with 2 migrations file like this:
class RemoveFieldsFromMt940Batches < ActiveRecord::Migration
def change
remove_column :mt940_batches, :account_number, :transaction_reference_number, :information_to_account_owner
end
end
class AddFieldsToMt940Batches < ActiveRecord::Migration
def change
add_column :mt940_batches, :created_by, :updated_by, :integer
end
end
Do not edit it if this migration already executed in production env create new one instead
if not you can use rake db:rollback, rollback migrations
Because this migration is already executed. you have to generate a new migration for adding and removing column in your table, i.e. you want to remove file_name from your table :
run this:
rails g migration RemoveFileNameFromCreateMt940Batches file_name:string
re-generate that column:
rails g migration AddFileNameToCreateMt940Batches file_name:string
Than run rake db:migrate it will remove column and add column again to your table.
Hope it will help. Thanks.
Create another migration file with removed column list
def change
remove_column :account_number, :transaction_reference_number, :information_to_account_owner
end
Create one migration file with added column list
def change
add_column :mt940_batches, :created_by, :updated_by, :integer
end
Do not alter the create table migration file. Other wise data saved in the file will be lost.
If data lost is not important for you, then just remove the table using rake db:migrate:down version=<your migration file version>
And change the migration file
then run
db:migrate:up version=<your migration file version>

index name too long to rollback migration

I'm on a git branch and trying to rollback two migrations, before destroying the branch. The most recent migration adds a column to a table that I want to keep (and which is part of master, not the branch to be dropped), so dropping the whole table is not a solution (unless I have to recreate it again). Anyways, I must have done something wrong, because when I tried to remove the apple_id column from the scores table, I got this abort error.
This is the migration that I'm trying to rollback
add_column :scores, :apple_id, :integer
However, the error message (see below) is referring to the indexes that I created with the original migration (part of master branch) that created the table
add_index :scores, [:user_id, :created_at, :funded, :started]
Can you suggest what I might do?
== AddAppleidColumnToScores: reverting =======================================
-- remove_column("scores", :apple_id)
rake aborted!
An error has occurred, this and all later migrations canceled:
Index name 'temp_index_altered_scores_on_user_id_and_created_at_and_funded_and_started' on table 'altered_scores' is too long; the limit is 64 characters
Update: reading this SO question How do I handle too long index names in a Ruby on Rails migration with MySQL?, I got some more information about the source of the problem but don't know how to solve it. Both sql and postgres have 64 character limits
Index name 'index_studies_on_user_id_and_university_id_and_subject_\
name_id_and_subject_type_id' on table 'studies' is too long; \
the limit is 64 characters
The accepted answer for the question I refer to says to give the index a name, although I'm not sure how I could do this now that I'm trying to rollback.
add_index :studies, ["user_id", "university_id", \
"subject_name_id", "subject_type_id"],
:unique => true, :name => 'my_index'
Update: in response to the comments, I'm using Rails 3.2.12. This is the migration that adds the column
class AddAppleidColumnToScores < ActiveRecord::Migration
def change
add_column :scores, :apple_id, :integer
end
end
Furthermore, the reason why I didn't want to drop the table was that I was unsure about what problems it might cause in recreating it since a) the main part was created on branch master, while a column added on a branch and b) I was unsure about what to do with the migration file for the dropped table? since it was the fourth (of about 10) tables I created, I don't know how to run it and only it again.
Can you copy/paste your migration?
Here's mine:
class AddAppleIdColumnToScores < ActiveRecord::Migration
def self.up
add_column :scores, :apple_id, :integer
add_index :scores, [:user_id, :created_at, :funded, :started]
end
def self.down
# delete index MySql way
# execute "DROP INDEX index_scores_on_user_id_and_created_at_and_funded_and_started ON scores"
# delete index Postgresql way
# execute "DROP INDEX index_scores_on_user_id_and_created_at_and_funded_and_started"
# delete index Rails way / not necessary if you remove the column
# remove_index :scores, [:user_id, :created_at, :funded, :started]
remove_column :scores, :apple_id
end
end

Migration issue in Ruby-on-rails

Hey guys, when I first begin a rails project, the model user was designed and created. After all the migration part, it successful created the table "users" at postgres.
Well, then after doing some changes during the project, I realized that was missing an attribute/new column at the table.
So what I did was delete the table users from postgres and add a new column at my first migration ruby class:
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :name
t.string :password
t.string :email
t.string :authorization_token //this is the new attribute that I insert
t.datetime :created_at
t.datetime :updated_at
t.timestamps
end
end
def self.down
drop_table :users
end
end
So, when I run again the db:migrate hopping that a new user table will be created with the new attribute :authorization_token, it doesn't work, but with no errors.
(I know that I should not remove the table, there is another smart way to do it)
A tip for working with Rails -- do not hand modify your tables using SQL. When you saw the problem you should have written a new migration like #nruth showed. Running the rake:migrate command would have worked fine for you.
In this case since you've already deleted your 'users' table you now have the problem that your database schema is out of sync with what Rails thinks it is. To fix this problem you can either get the database schema to roughly match what Rails thinks it is by hand creating the 'users' table, running the down migration and then then the up migration. Or you can get Rails up to speed with the fact that the 'users' table no longer exists. Rails stores migration info in either a schema_info table (Rails < 2.1) or schema_migrations table (Rails >= 2.1). If you remove that table then Rails will think the schema does not exist and try to run all the up migrations and recreate the 'users' table for you again.
Lastly, over time you may accumulate a number of migrations that individually add a column or two that you forgot to include. If you haven't yet shipped or aren't in production yet, then you can write a migration that sort of baselines your table. It would look something like this:
class CreateBaselineUsers < ActiveRecord::Migration
def self.up
create_table :users, :force => true do |t|
t.string :name
...
This will forcibly drop the table and recreate it with all the attributes that you want.
Migrations are run once & stored in the database as having been used (take a look in the schema_migrations table). You could try using rake db:migrate:reset to re-run your initial migration, but it's better to just add new migrations (you won't want to blow away your database when it has data in it) as follows:
script/generate migration add_authorization_token_to_users authorization_token:string
which will generate something similar to the following:
class AddAuthorizationTokenToUsers < ActiveRecord::Migration
def self.up
change_table :users do |t|
t.string :authorization_token //this is the new attribute that I insert
end
end
def self.down
remove_column :users, :authorization_token
end
end
To see how add/remove column, change_table, etc work, take a look at ActiveRecord::ConnectionAdapters::SchemaStatements at http://api.rubyonrails.org or http://guides.rubyonrails.org/migrations.html

Resources