Techioz Blog

Ruby および PostgreSQL の単一行モード

概要

Ruby を使用して PostgreSQL DB から行をフェッチしています。これは、pg gem サイト (https://deveiate.org/code/pg/PG/Result.html) で説明されているように、単一行モードで行われます。

conn.send_query( "first SQL query" )
conn.set_single_row_mode
conn.get_result.stream_each do |row|
    # do something with the received row of the first query
end

期待どおり、結果セットのすべての行を個別に取得します。ただし、大きな結果セットの場合、Ruby は結果セットをメモリ内に保持するようです。これにより、メモリが不足すると Ruby プログラムが終了します。

すでに処理された行のスペースを解放する方法はありますか? clear() または autoclear を使用する必要があると思いますか?しかし、それをどのように使用するのか、正確に何をクリアすればよいのかわかりません。

解決策

find_each accept を使用してみます (LIMIT と OFFSET を追加)

limit  = 1000
offset = 0

while do
  conn.send_query("SELECT * FROM users LIMIT #{limit} OFFSET #{offset}")
  conn.set_single_row_mode
  records = conn.get_result

  if records.any?
    limit  += 1000
    offset += limit
    sleep(5)
  else
    break
  end
  records.stream_each do |row|
    # do something with the received row of the first query
  end
end