我收到以下错误:
PGError: ERROR: operator does not exist: character varying >= integer
LINE 1: ...CT "games".* FROM "games" WHERE ("games"."uuid" >= 0) ORDE...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
: SELECT "games".* FROM "games" WHERE ("games"."uuid" >= 0) ORDER BY "games"."uuid" ASC LIMIT 1000
当我尝试这样做时:
Game.find_each do |game|
# ...
end
我的模型有一个字符串(UUID)主键:
class Game < ActiveRecord::Base
self.primary_key = 'uuid'
before_create do |game|
game.uuid = UUIDTools::UUID.timestamp_create().to_s if game.uuid.blank?
end
end
我不知道为什么ActiveRecord会放入WHERE
子句,但它完全没有必要和类型错误的原因(因为它是一个字符串列,而不是一个整数)。
那么,我该如何避免这种情况呢?我应该在模型定义中添加一些内容吗?或者我应该避免使用find_each
并使用其他方法吗?这是一个rake任务,只需遍历所有条目并查找其他一些信息......
答案 0 :(得分:4)
find_each
似乎有非数字主键错误:
https://groups.google.com/group/compositekeys/browse_frm/month/2011-06
答案 1 :(得分:1)
这个blog post可以解决您的错误:
在lib / clean_find_in_batches.rb
中module CleanFindInBatches
def self.included(base)
base.class_eval do
alias :old_find_in_batches :find_in_batches
alias :find_in_batches :replacement_find_in_batches
end
end
# Override due to implementation of regular find_in_batches
# conflicting using UUIDs
def replacement_find_in_batches(options = {}, &block)
relation = self
return old_find_in_batches(options, &block) if relation.primary_key.is_a?(Arel::Attributes::Integer)
# Throw errors like the real thing
if (finder_options = options.except(:batch_size)).present?
raise "You can't specify an order, it's forced to be #{batch_order}" if options[:order].present?
raise "You can't specify a limit, it's forced to be the batch_size" if options[:limit].present?
raise 'You can\'t specify start, it\'s forced to be 0 because the ID is a string' if options.delete(:start)
relation = apply_finder_options(finder_options)
end
# Compute the batch size
batch_size = options.delete(:batch_size) || 1000
offset = 0
# Get the relation and keep going over it until there's nothing left
relation = relation.except(:order).order(batch_order).limit(batch_size)
while (results = relation.offset(offset).limit(batch_size).all).any?
block.call results
offset += batch_size
end
nil
end
end
和config / initializers / clean_find_in_batches.rb
ActiveRecord::Batches.send(:include, CleanFindInBatches)
答案 2 :(得分:0)
我认为没有任何参数的find_each将导致find_by_id,其中id> = 0.即使ActiveRecord使用正确的列,在您的情况下,它似乎不知道该列是varchar类型,而不是整数。
您可以尝试使用其他find方法,也可以尝试在find_each中添加一些条件。
这可能与使用字符串作为主键的问题有关:http://railsforum.com/viewtopic.php?id=11110
干杯