Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I do something like find_in_batches_by_sql in Rails

find_in_batches does not allow pure SQL (so far as I can see).
find_by_sql does not have batch support (so far as I can see).

So how can I do something like find_in_batches_by_sql?

The SQL is nasty programatically generated stuff and it points to 3rd party databases and the result sets can have hundred-thousands to millions of records returned.

Are there other cursor tricks with ActiveRecord I should look into?

Thanks.

like image 351
Mark Bolusmjak Avatar asked Oct 11 '11 16:10

Mark Bolusmjak


People also ask

What are active records in Rails?

Rails Active Records provide an interface and binding between the tables in a relational database and the Ruby program code that manipulates database records. Ruby method names are automatically generated from the field names of database tables.

What is include in Rails?

Rails provides an ActiveRecord method called :includes which loads associated records in advance and limits the number of SQL queries made to the database. This technique is known as "eager loading" and in many cases will improve performance by a significant amount.


2 Answers

Updated to use the correct order for LIMIT and OFFSET

You could always break the SQL into parts and do something like

Model.select("*").where("WHERE CLAUSE HERE").joins("JOIN CLAUSES HERE").find_in_batches {...}

Or if you needed really fun SQL stuff you could just use an offset and limit and loop until you exhausted the results. Here's the basic idea:

offset = 0
limit = 1000

while(results)
  results = Model.find_by_sql("<your SQL here> LIMIT #{limit} OFFSET #{offset}")
  offset += limit  
  # Do stuff here
end
like image 167
Wizard of Ogz Avatar answered Oct 13 '22 10:10

Wizard of Ogz


Note offset should after limit

offset = 0
limit = 1000

while(results)
  results = Model.find_by_sql("<your SQL here>  LIMIT #{limit} OFFSET #{offset}")
  offset += limit  
  # Do stuff here
end
like image 44
sander Avatar answered Oct 13 '22 12:10

sander