如何识别 Rails 6 批量插入错误

Posted

技术标签:

【中文标题】如何识别 Rails 6 批量插入错误【英文标题】:How to identify Rails 6 bulk insert error 【发布时间】:2022-01-07 18:39:36 【问题描述】:

我建立了以下关系:

user has_many quizzes
quiz belongs_to user
quiz has_many questions
question belongs_to quiz

应用程序设置为使用 PostgreSQL。我正在尝试使用insert_all! 方法批量插入一堆记录

begin
  quiz = user.quizzes.create!(title: title, slug: slug)
  quiz_questions = params[:quiz][:questions].map! do |q|
    # creating an attribute hash here (code removed for conciseness of question)
  end
  result = quiz.questions.insert_all!(quiz_questions)

这引发了一个被我的“catch all”块捕获的错误

rescue ActiveRecord::ActiveRecordError
  render json:  message: ['Something went wrong'] , status: 500

正在运行的服务器控制台打印了这条消息:

TRANSACTION (0.9ms)  BEGIN
↳ app/controllers/quizzes_controller.rb:14:in `create'
Quiz Create (2.8ms)  INSERT INTO "quizzes" ("title", "user_id", "slug", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["title", "a quiz"], ["user_id", 1], ["slug", "a-quizk2DqYk"], ["created_at", "2021-12-01 05:00:05.800134"], ["updated_at", "2021-12-01 05:00:05.800134"]]
↳ app/controllers/quizzes_controller.rb:14:in `create'
TRANSACTION (1.6ms)  COMMIT
↳ app/controllers/quizzes_controller.rb:14:in `create'
Question Bulk Insert (0.6ms)  INSERT INTO "questions" ("question","a","b","c","d","score","answer","quiz_id") VALUES ('what is name', 'str', 'char', 'num', 'bool', 5, 'A', 1), ('die', 'yes', 'no', 'ok', 'what', 5, 'B', 1) RETURNING "id"
↳ (eval):6:in `block in insert_all!'
Completed 500 Internal Server Error in 153ms (Views: 0.2ms | ActiveRecord: 38.1ms | Allocations: 49609)

所以我认为我没有正确调用insert_all!,因为服务器只是在没有BEGINCOMMIT 书挡的情况下进行插入。另外,我想知道 catch all 块正在抛出和捕获哪个错误。 insert_all! 的正确做法是什么?

【问题讨论】:

【参考方案1】:

您可以将批量插入包装到事务中

def bulk_insert
  ActiveRecord::Base.transaction do
    quiz = user.quizzes.create!(title: title, slug: slug)
    quiz_questions = params[:quiz][:questions].map! do |q|
      # creating an attribute hash here 
      # ... 
      # note that you could validate attribute manually
      raise ActiveRecord::Rollback if q.description.blank?
    end
    result = quiz.questions.insert_all!(quiz_questions)
  end
rescue ActiveRecord::Rollback => e
 puts e
end

【讨论】:

我在这里发布后立即尝试了这个。 activerecord::Rollback 未被救援块捕获。 @kchak 交易成功了吗?我的意思是它是否回滚了quizquiz_questions(出现问题时)?除此之外,您可以尝试rescue StandardError 来捕获错误。 谢谢@Lam-Phan 我没有用 insert_all 试过这个!我认为当个别行无效时需要额外的逻辑。一旦我有时间做这件事,我会通知你的。

以上是关于如何识别 Rails 6 批量插入错误的主要内容,如果未能解决你的问题,请参考以下文章

Oracle批量插入数据时报字段无法识别错误

在 Rails 中批量插入时出错

如何在 Django 中执行批量插入?

如何使用 sqlite 批量插入超过 1000 条记录?

猫鼬批量插入错误

从文件批量插入引发错误无法批量加载,因为无法打开文件