Some people have been having trouble working with MySQL databases and
doing stuff like:
Item.filter(:active => true).each do |i|
i.do_something
i.save
end
And getting the dreaded 'Command out of sync' error. This is because
the each iterator fetches each record from the database, and trying to
update the databases or perform any other action while a query is
being executed is unsupported by the mysql library.
There are currently two solutions. The first is to load all records
into memory before iterating over them:
Item.filter(:active => true).all.each do |i|
i.do_something
i.save
end
This solution is fine if you have a small number of records, but may
be problematic for large datasets. The other solution is to use a
worker thread:
worker = Sequel::Worker.new
Item.filter(:active => true).each do |i|
worker.add do
i.do_something
i.save
end
end
worker.join
The worker thread performs the jobs using a separate database
connection and thus solves the problem. This is the best solution if
you're working with large datasets. You can also tell the worker to
wrap all its work in a transaction by giving it a database instant:
worker = Sequel::Worker.new(DB) # starts a transaction
Item.filter(:active => true).each do |i|
worker.add do
i.do_something
i.save
end
end
worker.join # transaction is commited
For those who do not want to use a worker thread, I propose changing
Dataset#all to act as iterator if a block is given, so people can do:
Item.filter(:active => true).all do |i|
i.do_something
i.save
end
sharon
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"sequel-talk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/sequel-talk?hl=en
-~----------~----~----~----~------~----~------~--~---