我是Rails的新手,我想知道在从CSV上传新数据时是否可以检查数据库中是否已存在数据。到目前为止,我还没有在网上找到这个。
我使用的是Postgres数据库。我不知道我是否必须在Rails或Postgres中查看它。在我的数据库中有一些列,例如id
,personal_id
,cost_center
。因此,我会在上传时检查我的新数据中的一个(或多个)是否与personal_id
具有相同的cost_center
。
我该怎么做?
更新
我已经尝试过@huan儿子的解决方案,它可行,但不是我需要的方式。所以我尝试了不同的东西,我认为SQL查询在我看来是最好的选择。
DELETE FROM bookings WHERE id NOT IN (SELECT MIN(id) FROM bookings GROUP BY personal_id, wbs, date, hours, cost_center)
Booking.delete_all.where('id NOT IN (?)', Booking.select('MIN(id)').group(:personal_id, :wbs, :date, :hours, :cost_center).map(&:id))
我的SQL查询就像我想要的那样,但我不知道正确的#34;翻译"进入rails,因为上面的第二个代码我的整个预订表被删除了
的解决方案
我的问题的解决方案是:
Booking.delete_all(['id NOT IN (?)', Booking.group(:personal_id, :wbs, :date, :hours, :cost_center).pluck('MIN(id)')])
答案 0 :(得分:0)
这些是独特的范围。
你需要先在数据库迁移中定义那些,所以postgres确保没有双值wie [key,key1,key2 ...]
add_index :table, [:personal_id, :cost_center_id], :unique => true
然后你需要进入你的rails模型并在验证时发现它的唯一性。
validates_uniqueness_of :personal_id, :scope => :cost_center_id
有了这个,rails每次都在创建一个对象,数据库之前进行查询,并检查是否已经存在具有唯一对值的东西。如果是这样,它将它添加到模型的@errors中,因此模型无法保存
答案 1 :(得分:0)
您可以使用唯一性验证,但根据我从CSV导入数据的经验,问题是如果项目已经存在,则所有验证都会停止保存记录。在大多数示例中,您通常希望对匹配的记录执行某些操作。因此,我建议你也看看find_or_initialize_by
。这允许您还从导入的数据更新现有记录。
因此,如果你有名称和成本的Thing模型,你可能想要按名称识别现有的东西,并更新它们的成本。并创建不存在匹配名称的新事物。以下代码可以做到这一点:
name, price = some_method_that_gets_name_and_price_from_csv
thing = Thing.find_or_initialize_by name: name
thing.price = price
thing.save
另请参阅find_or_create_by
,这在某些情况下可能更合适。我还会在模型中保持唯一性的验证。我只是不会使用验证来处理数据的导入方式。