Heroku have just introduced a limit on their free database of 10,000 rows. As their robots convert each of their Rails 3 apps to a new database architecture, any database approaching 10,000 rows will send out an email warning the user.
Mine came today:
The database HEROKU_POSTGRESQL_BRONZE_URL on Heroku app XXXXX is approaching its allocated storage capacity.
The database contains 8,387 rows. The plan allows a maximum of 10,000 rows.
It encourages the developer to upgrade to the a Basic database. (Bronze above refers to a label on the database, not the current type of database).
To get around that row limit I compressed an old table by removing some no-longer-required receipt records from the database and saved about 2700 rows. But how do I programmatically check the total number of rows that remain in the database now?
First, get the collection of ruby Models available in the application
ActiveRecord::Base.send :subclasses
Then we can loop over them, take a subtotal and output it to our command line.
st=0
ActiveRecord::Base.send(:subclasses).each do |sc|
st += sc.all.size
end
puts "Total number of rows is #{st.to_s}"
Or in a one liner:
st=0; ActiveRecord::Base.send(:subclasses).each {|sc| st += sc.all.size}; puts "Total number of rows is #{st.to_s}"
Update to this post
I recently added a non-ActiveRecord class (via the gem ‘slugged’) to my application. It means that the “sc.all” call fails, as “Slugged::Slug resolves to a string “Slugged::Slug(Table doesn’t exist).”
One way to work around this is to add in a try/catch block, which in Rails looks like this:
begin
// do something
rescue ActiveRecord::StatementInvalid
// response
end
or in our shorthand example looks like this:
st=0; ActiveRecord::Base.send(:subclasses).each {|sc| begin; st += sc.all.size unless sc.all.nil?; rescue ActiveRecord::StatementInvalid; end; }; puts "Total number of rows is #{st.to_s}"
If anyone has a better, more Railsy, way of doing this I’d love to hear it. Unfortunately sc.class resolves to “Class” in this case, and not String or Object so I can only respond to the exeception.