SamDonaldson wrote:
> Hello,
>
> It seems almost impossible to catch a mysql duplicate key exception
> through sqlalchemy. Can anybody help with understanding this? How do
> I catch a duplicate key exception in mysql? I tried catching the
> flush exception from sqlalchemy but that's definitely not doing the
> job. Do I have access to lower level dbapi exceptions that I can use
> in my code.
>
> Thanks.
>
Hi Sam,
The same problem exists for other databases (SQLite, etc). When I
ran into this problem earlier, I grepped code until I found that
SQLObject (not SQLAlchemy, but probably a similar situation) ONLY
returns an SQLObjectNotFound error... that's just about the only DB
error it traps, if no object is found by the query. Otherwise it just
passes the native RDBMS error message thru.
Each RDBMS behind these ORMs returns different errors, therefore it
is difficult to trap them all in a try:except pattern... the ORMs don't
give us that functionality per se. I think they could (pass through the
native errors), but they don't. And it's probably a good idea so that
the ORMs (SQLObject and Alchemy) remain high-level and above the fray of
which RDBMS to use behind the scenes. And also not have to keep up with
changing error message styles through all the many releases that each
RDBMS has had over the years.
Solution: One solution is to make your code test first for the
availability of that name you want to use, and build a try:except around
the message returned by your ORM if there is a name conflict.
Example: Using SQLObject, you can do something like this to create a
'save' method that tests for new page name collisions using
SQLObjectNotFound instead of getting the ugly duplicate name error message:
@expose()
def save(self, pagename, newpagename, data, submit):
if pagename == pagenewname:
page = Page.byPagename(pagename)
page.data = data
turbogears.flash("Page changes saved.")
raise redirect("/", pagename=newpagename)
else:
try:
page = Page.byPagename(newpagename)
except SQLObjectNotFound:
page = Page.byPagename(pagename)
page.pagename = newpagename
page.data = data
turbogears.flash("Page changes saved with a new name.")
raise redirect("/", pagename=newpagename)
page = Page.byPagename(pagename)
page.data = data
ermsg = "Sorry, that page name ('" + newpagename + \
"') is already in use. Choose another, or leave \
it as '" + pagename + "'."
turbogears.flash(ermsg)
raise redirect("/edit", pagename=pagename)
I don't really like this solution, as I don't like using try:except
error trapping in general, especially in this instance where it twists
the logic around in an unpythonic way. But it works for changing the
name on an already existing Page (as in a wiki, etc) and making sure
that there is not already one with that name being used.
For SQLAlchemy, I am not sure of the answer, but it seems that there
is no comparable error message to SQLObject's SQLObjectNotFound. If
there isn't one, then a query for an object with newname should likely
return None instead of some NotFound error... and you then can simply
test for the None value instead of for a NotFound error, and no
try:except will be needed.
In short, test your database with a query to make sure you won't have
a name collision first, then do the object save, rather than trying a
save first and getting a name collision error for your effort. It's the
equivalent of validating a form...
In fact, that would be a GREAT form validation trick... use
Ajax-style methods to check behind the scenes that a new name will be
valid BEFORE the user actually submits the form.
In fact, wouldn't it be nice if ALL validation of user form entries
were done by Ajax-style methods BEFORE the user ever gets to the point
of hitting the submit button? Do all the validation client-side or
using Ajax messaging that works as each form portion loses focus? Hmmmm.
Just thinking out loud now.
Hope there was help up there in my rambling, Sam.
Paul
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"TurboGears" 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/turbogears?hl=en
-~----------~----~----~----~------~----~------~--~---