4

次のエラーが発生します。

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または、別の方法を避けて使用する必要がありますか?これは、すべてのエントリを調べていくつかの追加情報を検索するレーキタスク用です...

4

3 に答える 3

4

find_each数値以外の主キーにバグがあるようです:

https://groups.google.com/group/compositekeys/browse_frm/month/2011-06

于 2012-05-31T13:33:00.030 に答える
0

このブログ投稿には、バグの修正が含まれています。

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)
于 2014-07-18T02:31:43.177 に答える
0

パラメーターなしの find_each は、id >= 0 の find_by_id になると思います。ActiveRecord は正しい列を使用しますが、あなたの場合、列が整数ではなく varchar 型であることを認識していないようです。

別の find メソッドを使用するか、find_each にいくつかの条件を追加してみてください。

これは、文字列を主キーとして使用する問題に関連している可能性があります: http://railsforum.com/viewtopic.php?id=11110

乾杯

于 2012-05-31T13:35:28.137 に答える