0

我正在尝试运行迁移,但每当我尝试时,我都会收到错误“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是字符串。

另外,我刚刚想到 - 错误是否可能是数据库问题的结果?例如,它可能以某种方式部分损坏?数据库类型为 SQLite3。

4

1 回答 1

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

无效数据完全有可能不在电子邮件字段中,在这种情况下,您需要对每个字符串字段执行类似的操作以确定罪魁祸首

于 2012-06-06T02:14:05.657 回答