On Tue, Jul 7, 2009 at 9:05 PM, Steve Howell <[email protected]> wrote:
> > On Jul 7, 3:07 pm, Karen Tracey <[email protected]> wrote: > > > > > > > On Jun 29, 10:53 am, Steve Howell <[email protected]> wrote: > > > > Hi, I have created a management command that populates some tables in > > > > a Postgres database, and I use the handy get_or_create() method in > db/ > > > > models/query.py. I tried running a command recently where I had > > > > inadvertently left some foreign key references dangling around, > > > > Could you be a little more specific about what the error was in your > code? > > Sorry I never reported the error, but, of course, part of my problem > was that the error was caught by the try/except in Django code. > > I did the following sequence, conceptually: > > 1) I had a database with books and authors. > 2) I received a new feed of books. > 3) I cleaned the books table without cleaning the authors table. > 4) When I tried to import the first book, there was still a stale > author. > 5) Instead of getting the normal integrity error, I got the red > herring savepoint error. > 6) When I went back and cleaned BOTH tables, everything worked fine. > > > > From looking at the full get_or_create routine you include below it isn't > > immediately obvious to me where it might be raising an IntegrityError > before > > the savepoint is created, yet it sounds like that is what is happening. > We > > need to understand how that is happening before figuring out what the > right > > fix is. > > > > If memory serves correctly, it was this line that raised the original > error: > > obj.save(force_insert=True) > > > Here's the code in more context: > > try: > params = dict([(k, v) for k, v in kwargs.items() if > '__' not in k]) > params.update(defaults) > obj = self.model(**params) > sid = transaction.savepoint() > obj.save(force_insert=True) > transaction.savepoint_commit(sid) > return obj, True > except IntegrityError, e: > transaction.savepoint_rollback(sid) > try: > return self.get(**kwargs), False > except self.model.DoesNotExist: > raise e > But if it's the obj.save(force_insert=True) that is causing the IntegrityError, then the savepoint should have been created by the immediately preceding line: 'sid = transaction.savepoint()'. Thus attempting to rollback that savepoint should not fail. I was thinking you were hitting the IntegrityError earlier, before the savepoint had been created (though I couldn't see where that could possibly be happening), but if that were the case I think you'd be getting a Python error about sid being referenced before being set. So, the savepoint has been created but the DB doesn't seem to know about it, which is a bit of a mystery. If you look at that code you see it tries to not swallow any IntegrityErrors that aren't in fact due to collisions on insert. If the save fails, it tries the get again, and if that again returns DoesNotExist then the original IntegrityError e is raised. You have hit an unexpected case where the savepoint rollback is failing. As the code is written I don't see how that could be failing, and I don't have time to try to recreate myself right now. What version of PostgreSQL are you running? Karen --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django users" 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/django-users?hl=en -~----------~----~----~----~------~----~------~--~---

