当前位置: 首页 > 知识库问答 >
问题:

活动记录导入正在创建重复记录

郭俊人
2023-03-14

我在类方法中使用active record 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

根据active record导入文档,我正在尝试将列表的标题和VIN字段设置为冲突目标。如果列表的VIN字段发生冲突,我希望进行更新,而不是创建。

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

我哪里出错了?

共有1个答案

李开宇
2023-03-14

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

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

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

由于数据库没有报告唯一约束上的冲突,因此它没有理由更新现有行!在这个堆栈溢出问题中,“如何在postgres 9.5中正确地进行更新”的答案更深入地解释了这一点,并显示了正在发出的查询类型。

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

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

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

  • activerecord导入生成这些查询的源代码
  • PostgreSQL UPSERT详细信息
  • MySQL UPSERT引用
 类似资料:
  • 我使用JBOSS 5.1.2 MDB来使用放置在队列中的实体消息。消息生成器可以为同一实体生成多条消息。这些消息实体由它们的实体编号定义。(msg_entity_no)只有当实体不存在时,我才必须将记录插入到现有实体表中,否则我必须更新现有记录。现有实体表在此实体号上不唯一,因为它有另一个内部键。ie它包含重复的msg_entity_no 我遇到的问题是,当产生多个消息时,实体表中同时存在多个MD

  • 问题内容: 我正在看一个问题:从SQLite表获取随机值,这使我想知道是否可以使用SQL复制记录。更具体地说,有没有一种可以转换这些记录的构造: 进入: 后者中的和记录的计数与前一组记录中的对应值匹配。 可以用SQL完成吗?如果是这样,怎么办? 编辑: Lucero问什么SQL方言?任何真的,但理想情况下,最不可知论的方法都是最好的。 另一个编辑: 是否可以在sqlite中的单个SQL语句中完成?

  • 我们有一个列的表:datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 当我们从活动记录更新它时,插入查询包含created_at和updated_at列。 即使在设置配置之后。活动记录。record_timestamp

  • 问题内容: 有没有办法一次插入多个记录而不是一次插入? 我有一个非常丑陋的耙子任务,正在做以下事情… 这必须非常低效,并且必须有更好的方法… 问题答案: 该方法也将数组作为参数。 但是,它仍然对每个条目执行一个SQL查询,而不是单个SQL查询。它效率更高,因为它只需要在后台创建一个activerecord对象。 如果要同时从同一客户端插入许多行,请使用带有多个VALUES列表的INSERT语句一次

  • Active Record 提供了一个面向对象的接口, 用以访问和操作数据库中的数据。Active Record 类与数据库表关联, Active Record 实例对应于该表的一行, Active Record 实例的属性表示该行中特定列的值。 您可以访问 Active Record 属性并调用 Active Record 方法来访问和操作存储在数据库表中的数据, 而不用编写原始 SQL 语句。

  • 问题内容: 我的本地计算机上有一个数据库,我想将数据导入主机上的数据库。这两个数据库的是相同的,相同的,等等。 当我从本地数据库通过该表并通过我的主机上的phpmyadmin 通过该表时,会弹出一个错误消息,告诉我存在重复的条目并停止了整个操作。 如何通过phpmyadmin导入数据,跳过重复的条目,并在流程结束时显示重复的列表? 我可以做的一个解决方案是在主机上调用数据库中主键的所有值,并在导入