On Sun, 2007-11-11 at 20:44 -0800, marknca wrote:
> According to a previous (http://groups.google.com/group/django-users/
> browse_thread/thread/64a9558d5c02e39/c0c28daed410898d?lnk=gst&q=catch
> +save+exception#c0c28daed410898d) post it's bad practice to wrap a
> model's .save() in a try/except. Adrian suggests using manipulators
> instead.

Bear in mind that the thread you referenced is over two years old. A few
things have changed since then. The obvious one being that
IntegrityError is now in the django.db namespace, so you don't need to
write database-specific code. That wasn't true back in November '05.

Secondly, IntegrityError is one of the few exceptions save() can raise.
The problem is that there are some things you just can't tell until you
talk to the database. In particular, whether a particular set of
database column constraints will be satisfied (a unique combination, or
a check constraint). So sometimes the database will raise IntegrityError
for reasons you can't control that (what if another process altogether
had written to the database?). This isn't always going to happen and
most of the time, you, the developer, will know what sort of database
access patterns to expect and whether it's likely/possible something
else will have written to the database.

All being said, though, the principle Adrian espoused in that thread is
correct: validation errors that can be detected at the Python level
shouldn't ever be raised from save(). However, there are some errors we
can't detect until we talk to the db, which only happens in save(). I
think it'd be really nice to have validators able to also verify that
database constraints were true (and guarantee they will remain true
until you call save() and commit the data to the db), however that's not
always possible.

[...]
> The test case failes by raising an IntegrityError even though I'm
> trapping it and asserting success if this Exception  is thrown.

You're calling the save() method in a few places and only catching
IntegrityError in one of those cases (the last one). I'll wager that the
place raising the error is not the line you think it is.

>  I had
> re-written this sequence a few times with the same results.
> 
> 1) Why can't I trap the IntegrityError in my test case?
> 
> 2) What is the best practice for writing test cases to validate that
> only unique data is being saved to the database?

Whatever works is usually good enough. You can catch IntegrityError. Or
you can select all the rows matching that particular value out at the
end and confirm there is only one object returned (although presumably
that will raise IntegrityError when you tried to save).

> Bonus question:
> 
> 1) Does self.failUnlessRaises() work with Python 2.4? Replacing the
> bottom section of the test case with self.failUnlessRaises() does not
> work on my Ubuntu 6.06 server w/Python 2.4 and the latest Django SVN
> release.

"Does not work" could mean many things. Since we're not psychic, it's
difficult to divine what actually happened in your case.
failUnlessRaises() exists at least as far back as python 2.3, though (as
a quick check of the online Python docs confirms).

Regards,
Malcolm

-- 
Quantum mechanics: the dreams stuff is made of. 
http://www.pointy-stick.com/blog/


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to