我正在尝试运行迁移,但每当我尝试获取错误“UTF-8中的无效字节序列”时。这是迁移:
class ChangeSchoolEmailToApplicationEmail < ActiveRecord::Migration
def self.up
rename_column :users, :school_email, :application_email
end
def self.down
rename_column :users, :application_email, :school_email
end
end
如果我只运行rake db:migrate
,我会收到需要使用bundle exec的消息。所以我最后使用的命令是bundle exec rake db:migrate
,它会产生以下错误:
C:\Rails\qsn>bundle exec rake db:migrate
== ChangeSchoolEmailToApplicationEmail: migrating ============================
-- rename_column(:users, :school_email, :application_email)
rake aborted!
An error has occurred, this and all later migrations canceled:
invalid byte sequence in UTF-8
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
帮助表示赞赏!
修改
使用--trace
输出如下:
C:\Rails\qsn>bundle exec rake db:migrate --trace
** Invoke db:migrate (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute db:migrate
== ChangeSchoolEmailToApplicationEmail: migrating ============================
-- rename_column(:users, :school_email, :application_email)
rake aborted!
An error has occurred, this and all later migrations canceled:
invalid byte sequence in UTF-8
C:/Ruby/lib/ruby/gems/1.9.1/gems/sqlite3-1.3.4-x86-mingw32/lib/sqlite3/database.rb:48:in `gsub'
C:/Ruby/lib/ruby/gems/1.9.1/gems/sqlite3-1.3.4-x86-mingw32/lib/sqlite3/database.rb:48:in `quote'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/connection_adapters/sqlite_adapter.rb:114:in `quote_string'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/connection_adapters/abstract/quoting.rb:21:in `quote'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/connection_adapters/sqlite3_adapter.rb:45:in `quote'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/connection_adapters/sqlite_adapter.rb:372:in `block (2 levels) in copy_table_con
tents'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/connection_adapters/sqlite_adapter.rb:372:in `map'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/connection_adapters/sqlite_adapter.rb:372:in `block in copy_table_contents'
C:/Ruby/lib/ruby/gems/1.9.1/gems/sqlite3-1.3.4-x86-mingw32/lib/sqlite3/database.rb:142:in `block (2 levels) in execute'
C:/Ruby/lib/ruby/gems/1.9.1/gems/sqlite3-1.3.4-x86-mingw32/lib/sqlite3/statement.rb:110:in `block in each'
C:/Ruby/lib/ruby/gems/1.9.1/gems/sqlite3-1.3.4-x86-mingw32/lib/sqlite3/statement.rb:107:in `loop'
C:/Ruby/lib/ruby/gems/1.9.1/gems/sqlite3-1.3.4-x86-mingw32/lib/sqlite3/statement.rb:107:in `each'
C:/Ruby/lib/ruby/gems/1.9.1/gems/sqlite3-1.3.4-x86-mingw32/lib/sqlite3/database.rb:140:in `block in execute'
C:/Ruby/lib/ruby/gems/1.9.1/gems/sqlite3-1.3.4-x86-mingw32/lib/sqlite3/database.rb:95:in `prepare'
C:/Ruby/lib/ruby/gems/1.9.1/gems/sqlite3-1.3.4-x86-mingw32/lib/sqlite3/database.rb:134:in `execute'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/connection_adapters/sqlite_adapter.rb:370:in `copy_table_contents'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/connection_adapters/sqlite_adapter.rb:334:in `copy_table'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/connection_adapters/sqlite_adapter.rb:311:in `move_table'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/connection_adapters/sqlite_adapter.rb:304:in `block in alter_table'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/connection_adapters/abstract/database_statements.rb:139:in `transaction'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/connection_adapters/sqlite_adapter.rb:303:in `alter_table'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/connection_adapters/sqlite_adapter.rb:275:in `rename_column'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/migration.rb:385:in `block in method_missing'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/migration.rb:361:in `block in say_with_time'
C:/Ruby/lib/ruby/1.9.1/benchmark.rb:295:in `measure'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/migration.rb:361:in `say_with_time'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/migration.rb:381:in `method_missing'
C:/Rails/qsn/db/migrate/20120606013213_change_school_email_to_application_email.rb:3:in `up'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/migration.rb:314:in `block in migrate'
C:/Ruby/lib/ruby/1.9.1/benchmark.rb:295:in `measure'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/migration.rb:314:in `migrate'
C:in `migrate'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/migration.rb:539:in `block (2 levels) in migrate'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/migration.rb:613:in `call'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/migration.rb:613:in `block in ddl_transaction'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/connection_adapters/abstract/database_statements.rb:139:in `transaction'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/transactions.rb:207:in `transaction'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/migration.rb:613:in `ddl_transaction'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/migration.rb:538:in `block in migrate'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/migration.rb:525:in `each'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/migration.rb:525:in `migrate'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/migration.rb:435:in `up'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/migration.rb:417:in `migrate'
C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.9/lib/active_record/railties/databases.rake:142:in `block (2 levels) in <top (required)>'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/task.rb:205:in `call'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/task.rb:205:in `block in execute'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/task.rb:200:in `each'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/task.rb:200:in `execute'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/task.rb:158:in `block in invoke_with_call_chain'
C:/Ruby/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/task.rb:151:in `invoke_with_call_chain'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/task.rb:144:in `invoke'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/application.rb:112:in `invoke_task'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/application.rb:90:in `block (2 levels) in top_level'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/application.rb:90:in `each'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/application.rb:90:in `block in top_level'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/application.rb:129:in `standard_exception_handling'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/application.rb:84:in `top_level'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/application.rb:62:in `block in run'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/application.rb:129:in `standard_exception_handling'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/application.rb:59:in `run'
C:/Ruby/lib/ruby/gems/1.9.1/gems/rake-0.9.2/bin/rake:32:in `<top (required)>'
C:/Ruby/lib/ruby/gems/1.9.1/bin/rake:19:in `load'
C:/Ruby/lib/ruby/gems/1.9.1/bin/rake:19:in `<main>'
Tasks: TOP => db:migrate
修改
school_email
的类型是String。
另外,我只是想到 - 错误可能是数据库中出现问题的结果?比如,它可能会以某种方式部分腐败?数据库类型是SQLite3。
答案 0 :(得分:2)
在SQLite中重命名列(不支持重命名)时,需要重新创建表,并且需要重新插入数据。显然,它目前拥有的一些数据不是UTF-8编码的。最可能的原因是数据损坏,尽管我不确定UTF-8规则是否存在允许此类数据在奇怪情况下传入的例外情况。
在执行迁移之前,您需要修复数据,因此请尝试搜索无效数据并进行修复:
User.all.each do |user|
email = user.school_email
email.force_encoding "utf-8"
unless email.valid_encoding?
puts "Invalid email: #{email} in user id: #{user.id}"
email.encode!("utf-8", "utf-8", :invalid => :replace)
user.update_attribute(:school_email, email)
end
end
完全有可能无效数据不在电子邮件字段中,在这种情况下,您需要为每个字符串字段执行类似操作以确定罪魁祸首