ruby-on-rails - 事件记录导入正在创建重复记录

标签 ruby-on-rails csv activerecord bulkinsert activerecord-import

我在类方法中使用事件记录导入 gem 来导入从 csv 文件读取的列表数组,如下面的代码所示:

def self.import_listings(file)  
        start = Time.now    
        count = 0
        valid_listings = Array.new

        CSV.foreach(file.path, headers: true, encoding:'iso-8859-1:utf-8') do |row|

            data = {}

            row.to_hash.each do |k, v|
                key = MAP[k]
                data[key] = v
            end

            unless data[:vin] == nil            
                listing =  Listing.new                      
                listing.title = "#{data[:year]} #{data[:make]} #{data[:model]}"


                listing.approved = true


                unless data[:all_images] == nil

                    listing_images = data[:all_images].split(",")
                    i = 0

                    [:image, :imagefront, :imageback, :imageleft, :imageright, :frontinterior, :rearinterior].each do |image|               
                        unless listing_images.size < 1
                            data[image] = CsvUploading::picture_from_url(listing_images[i])
                            i += 1
                        end

                    end

                end


                data.delete(:all_images)

                data[:approved] = true


                listing.attributes = data


                valid_listings << listing

             end
        end



        begin

            Listing.import valid_listings, on_duplicate_key_update: { conflict_target: [:title, :vin], columns: [user_id: :user_id, newused: :newused]}# , :stocknumber, :model, :year, :trim, :miles, :enginedescription,:cylinder,:fuel,:transmission,  :price, :color, :interiorcolor, :options, :description, :image, :image, :imagefront, :imageback, :imageleft, :imageright, :frontinterior, :rearinterior]

        rescue
            p "some issue"
        end

        finish = Time.now
        puts diff = finish - start                          
    end

根据事件记录导入文档,我试图在列表的标题和 VIN 字段上设置一个观察者作为冲突目标。如果列表的 VIN 字段发生冲突,我想进行更新而不是创建.

但现在,每次我运行 CSV 上传时,它都会从 Listing.import 创建一个新列表,而不检查它是否有冲突。

我哪里错了?

enter image description here

最佳答案

您的屏幕截图显示您正在使用 SQLite,但是 documentation表示此功能仅支持 MySQL 和 PostgreSQL。您将需要使用受支持的数据库!


我的第一个答案,以防将来对某人有用:

On Duplicate Key Update行为取决于数据库本身对这些列的唯一约束——因为您看到的是重复记录,所以可以安全地假设您没有这样的约束。

由于数据库未报告唯一约束的冲突,因此它没有理由更新现有行! this Stack Overflow question, "How to correctly do upsert in postgres 9.5"中的答案对此进行了更深入的解释,并显示了正在发出的查询类型。

您应该能够通过在 VIN 和标题列上添加唯一约束或索引来解决此问题,例如执行如下操作的 Rails 迁移:

class AddUniqueIndexToListingsOnVinAndTitle < ActiveRecord::Migration
  def change
    add_index :listings, [:vin, :title], unique: true
  end
end

一些您可能会觉得有用的信息(不确定您使用的是 PostgreSQL 还是 MySQL):

关于ruby-on-rails - 事件记录导入正在创建重复记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48033064/

相关文章:

ruby-on-rails - 如何让 ruby​​ 脚本在 Heroku 上的 Rails 应用程序中持续运行?

javascript - Rails - 使用新表条目刷新页面

CSS 可用但在推送到生产环境时不呈现 [Rails 应用程序]

mysql - ruby on Rails Mysql在ubuntu上安装问题

Python:无法保存到 CSV

python - 读取包内的csv文件

ruby - 在 Ruby 中将数组输出到 CSV

ruby-on-rails - Rails 4.0.1 和 HAML 中的 `undefined method ` [] ' for nil:NilClass`

php - 检查php mysql事件记录中是否不存在数据然后选择默认代码

ruby-on-rails - 获取 Ruby 变量引用的对象