2011-10-24 50 views
25

Tôi đã tạo ra một cơ sở dữ liệu với phát minh và máy phát điện tiện lợi. Tôi đang cố gắng để tạo ra một cơ sở dữ liệu mới với các máy phát điện tiện lợi (rails g nifty:scaffold Asset user_id:integer), nhưng khi tôi cố gắng để di chuyển cơ sở dữ liệu (rake db:migrate), tôi nhận được lỗi sau:Rake bị hủy bỏ ... bảng 'người dùng' đã tồn tại

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) 

Tôi đang theo một hướng dẫn và có khá khó hiểu tại sao điều này lại xảy ra. Bất cứ ai có thể giải thích những gì đang xảy ra?

Trả lời

11

Việc di chuyển đang cố gắng tạo bảng đã tồn tại trong cơ sở dữ liệu của bạn.

Cố gắng xóa bảng người dùng khỏi cơ sở dữ liệu của bạn. Đã xảy ra sự cố với quy trình di chuyển của bạn. Bạn cũng nên so sánh phiên bản schema.rb của bạn với các tệp db/migrate/* .bb của bạn.

Làm rõ:

Dường như nhiều SO người dùng không đồng ý với trả lời của tôi, hoặc vì họ coi đó là không chính xác hoặc không được khuyến khích.

Xóa bảng luôn luôn phá hoại và tôi nghĩ rằng mọi người đều hiểu điều đó.

Tôi đã đề cập đến add_column, vì bảng đã được tạo trong tệp di chuyển khác.

+39

Chỉ cần xóa bảng? Đó là một giải pháp khủng khiếp. –

+1

Tôi muốn biết giải pháp của bạn. –

+12

Điều này hiển nhiên, nhưng tôi muốn làm rõ cho bất kỳ ai thực hiện điều này ... ** Dữ liệu của bạn trong bảng đó sẽ bị mất **. –

58

Trong di chuyển create_users của bạn (APP_ROOT/db/migrate/..), thêm drop_table :users ngay trước create_table :users và chạy rake db:migrate. Nó sẽ loại bỏ bảng người dùng trước khi tạo lại nó. Bạn có thể xóa dòng mã đó sau khi chạy di chuyển này để nó không cung cấp cho bạn các lỗi sau này. Chỉ cần sửa chữa nhỏ nếu bạn không có quyền truy cập UI vào cơ sở dữ liệu (ví dụ: trên heroku).

+0

Cả hai giải pháp bán làm việc ... Có vẻ như tôi thực sự đã làm điều gì đó sai trái trong tính toàn diện, vì vậy tôi đã lùi lại một vài bước và làm lại nó. Cảm ơn rất nhiều cho các giải pháp tuyệt vời mặc dù. –

+13

Điều này là hiển nhiên, nhưng tôi muốn làm rõ cho bất kỳ ai thực hiện điều này ... ** Dữ liệu của bạn trong bảng đó sẽ bị mất **. –

+0

Dope. cảm ơn anh bạn. –

10

Nếu bạn biết cơ sở dữ liệu đã được tạo đúng cách, bạn chỉ có thể nhận xét phần tạo mã di chuyển. Ví dụ:

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 

Nếu bảng đã được tạo ra, nhưng lệnh này sau đó đã không hoàn thành đối với một số lý do, bạn chỉ có thể để lại các tùy chọn sau ví dụ:

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 

Nếu bạn không có bất kỳ dữ liệu quan trọng trong cơ sở dữ liệu của bạn để bảo tồn tuy nhiên bạn chỉ có thể có nó thả bảng và tất cả các dữ liệu và tạo ra nó tươi. Ví dụ (thông báo là "drop_table: phiếu", trong 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 
1

Tôi nghĩ rằng đây là một vấn đề duy nhất hoặc phổ biến hơn để mysql trong đường ray, có thể cần phải làm với các viên ngọc mysql2 chinh no.

Tôi biết điều này vì tôi vừa chuyển từ sqlite sang mysql và chỉ bắt đầu gặp sự cố này một cách có hệ thống.

Trong trường hợp của mình, tôi chỉ đơn giản là nhận xét mã đã chạy và chạy lại di chuyển (mà tôi không thêm chi tiết nữa vì có vẻ như anh chàng trên tôi đã làm điều đó).

1

Tôi gặp sự cố tương tự khi cố gắng thêm xác thực Devise vào bảng Người dùng hiện tại.

Giải pháp của tôi: Tôi thấy rằng tôi có hai tệp di chuyển, cả hai đều cố gắng tạo bảng Người dùng. Vì vậy, thay vì xóa bảng (có lẽ không phải là thói quen tốt nhất để tạo thành), tôi đã nhận xét tệp di chuyển đầu tiên (ban đầu) đã tạo bảng Người dùng và sau đó rời tệp di chuyển Devise as-is. Chạy lại quá trình di chuyển và nó hoạt động tốt.

Khi nó quay ra, tệp Devise không gây ra sự cố; Tôi có thể thấy rằng đó là "thay đổi" bảng, không phải "tạo ra nó", có nghĩa là ngay cả khi không có cài đặt phát sinh, một db: di chuyển có thể sẽ gây ra cùng một vấn đề (mặc dù tôi chưa thử nghiệm điều này).

21

Bạn cần phải thả bảng từ SQL Lite console (Bạn sẽ mất tất cả dữ liệu chứa trong nó)

  1. Tiếp cận lite sql console, gõ vào terminal
    mysql <DB NAME HERE>

  2. Bảng thả (đừng quên lần cuối cùng ; (dấu chấm phẩy))
    drop table table_name;

  3. chạy db: di chuyển lại
    bin/rake db:migrate

Hy vọng nó giúp, nó làm việc cho tôi

+0

Câu hỏi đặt ra là về MySQL chứ không phải Sqlite. –

+0

chỉnh sửa đúng cho mysql –

11

Nếu bạn chơi muốn an toàn và không muốn để mất bất kỳ dữ liệu thì bạn có thể kiểm tra xem bảng tồn tại trong cơ sở dữ liệu của bạn.

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 
0

Nếu bạn muốn giữ cho dữ liệu của bạn, đổi tên bàn, nhưng làm điều đó trong việc chuyển đổi sang tiết kiệm thời gian, sau đó loại bỏ nó một lần di cư đã chạy.

Đặt ở phần trên cùng của phần lên của tệp di chuyển.

rename_table :users, :users2 
4

Không xóa bảng. Dữ liệu > di chuyển!

Phiên bản của cơ sở dữ liệu đã phản ánh những thay đổi mà quá trình di chuyển gây ra lỗi đang cố thêm. Nói cách khác, nếu di chuyển có thể bị bỏ qua, thì mọi thứ sẽ ổn. Kiểm tra bảng db_schema_migrations và thử chèn phiên bản di chuyển sai (e.x, 20151004034808). Trong trường hợp của tôi, điều này gây ra sự di chuyển tiếp theo để thực thi một cách hoàn hảo và mọi thứ có vẻ ổn.

Vẫn không chắc chắn nguyên nhân gây ra sự cố này.

Các vấn đề liên quan