The only reason I'm not using models and validations is because this code is part of an import library that is pulling in a few thousands of rows in an hour's time and the models approach was a lot slower than pure datasets. I also found the imports a *lot* faster to load and handle exceptions when the database complains vs. pre-validation.
I should mention that a lot of testing and design of the importer routines I developed happened prior to your optimizations efforts that have come out in the last couple years, so models may perform on par with datasets these days, but I don't really know if this is the case since I'm running entirely with datasets with my own simple class wrappers. What I do know is that I was far outpacing similar efforts with ActiveRecord, so Sequel became a staple in my Ruby toolbox because of this (not to mention the ability to construct complex SQL with pure Ruby DSL). Michael On Sun, Jan 20, 2013 at 4:38 PM, Jeremy Evans <[email protected]> wrote: > On Sunday, January 20, 2013 12:27:52 PM UTC-8, Michael Lang wrote: >> >> > this. Most people who would need such a thing are probably using models >> > with validates_unique, and probably don't have a problem with raising a >> > regular exception if the race is lost. That being said, it seems like a >> > useful thing to me, so I'll look into implementing it. >> > >> Or...they roll their own...I usually try to report on exactly what goes >> wrong... >> >> class DataWouldBeTruncated < DatabaseError >> end >> >> class InvalidDateError < DatabaseError >> end >> >> class Patient >> >> def raise_whats_too_long >> DB.schema(:patient).each do |col| >> if col[1][:db_type] == 'varchar' and @values[col[0]].size > >> col[1][:max_chars] >> raise DataWouldBeTruncated, "#{col[0]} is too long with >> [#{@values[col[0]]}]" >> end >> end >> raise DataWouldBeTruncated, "A field has an data that is too long >> to save for record #{id}" >> end >> >> def parseble_date(value) >> begin >> !!Date.parse(value) >> rescue >> nil >> end >> end >> >> def raise_what_date_has_error >> DB.schema(:patient).each do |col| >> if col[1][:db_type] =~ /date/ and !parseable_date(@values[col[0]]) >> raise InvalidDateError, "#{col[0]} has invalid date value: >> [#{@values[col[0]]}]" >> end >> end >> raise InvalidDateError, "A date field has an invalid value for record >> #{id}" >> end >> >> def insert >> begin >> DB[:patient].insert(@values) >> rescue Exception => e >> if e.message =~ /data would be truncated/ >> raise_whats_too_long >> elsif e.message =~ /conversion of a char data type to a datetime/ >> raise_what_date_has_error >> else >> raise >> end >> end >> end >> end >> >> Probably much harder to generalize such an approach as above, but I >> would definitely like to see more specific errors emitting from the >> Sequel library. > > > I'm pretty sure almost anyone that is doing something similar to what you > are doing is using models with validations. Don't get me wrong, having > constraints in the database is the recommended approach, but if you want to > report specific error messages, it's better to also do validation in ruby > before sending it to the database. The constraint_validations > plugin/extension helps do this without duplication, but for other types of > constraints, it can still be done with a little duplication. > > Both of your examples for truncation and bad char->datetime conversion can > be handled by validations, so they would not be candidates for specific > Sequel exception classes. For unique constraints, it may be worth making an > exception (pun intended), as those cannot be handled in a raceless manner by > a validation. Looks like ActiveRecord also has an exception class for > invalid foreign keys, which are another case that cannot be handled in a > raceless manner by a validation, so I suppose I would consider a special > exception for that as well. > > Thanks, > Jeremy > > -- > You received this message because you are subscribed to the Google Groups > "sequel-talk" group. > To view this discussion on the web visit > https://groups.google.com/d/msg/sequel-talk/-/B9imW_McZRUJ. > > 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. -- http://codeconnoisseur.org -- 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.
