Strange Bug

33 views
Skip to first unread message

Neto

unread,
Apr 22, 2016, 4:59:25 AM4/22/16
to Django users
I'm trying to delete but it's happening a strange error.

models:
class Account(models.Model):
    pass


class Action(models.Model):
    account = models.ForeignKey('Account', on_delete=models.CASCADE)


class Log(models.Model):
    account 
= models.ForeignKey('Account', on_delete=models.CASCADE)


class ActionLog(Log):
    action 
= models.ForeignKey('Action', on_delete=models.SET_NULL)


shell:

account = Account.objects.create()
action
= Action.objects.create(account=account)
ActionLog.objects.create(account=account, action=action)
account
.delete()


error:
insert or update on table "myapp_log" violates foreign key constraint "myapp_log_account_id_6ea8d7a6_fk_myapp_account_id"
DETAIL:  Key (account_id)=(11) is not present in table "myapp_account".
But:
>>> Account.objects.last().id
11


Why it happen? How solve it? Is a bug?
I am using PostgreSQL 9.3 and Django 1.9.5

Erik Cederstrand

unread,
Apr 22, 2016, 6:47:31 AM4/22/16
to Django Users
Hi Neto,

> Den 22. apr. 2016 kl. 06.59 skrev Neto <paulosou...@gmail.com>:
>
> [...]
> class ActionLog(Log):
> action = models.ForeignKey('Action', on_delete=models.SET_NULL)
>
> [...]
>
> ActionLog.objects.create(account=account, action=action)

Something's wrong with your example. The ActionLog class only has an 'action' field, but you're creating an ActionLog instance as if it has both 'action' and 'account'.

Erik

Neto

unread,
Apr 22, 2016, 3:37:48 PM4/22/16
to Django users
Erick, ActionLog is inheriting Log. Please, pay attention before commenting, and see that the error has nothing to do with what you said.

Michal Petrucha

unread,
Apr 22, 2016, 6:08:19 PM4/22/16
to django...@googlegroups.com
> Em sexta-feira, 22 de abril de 2016 01:59:25 UTC-3, Neto escreveu:
> >
> > I'm trying to delete but it's happening a strange error.
> >
> > models:
> > class Account(models.Model):
> > pass
> >
> >
> > class Action(models.Model):
> > account = models.ForeignKey('Account', on_delete=models.CASCADE)
> >
> >
> > class Log(models.Model):
> > account = models.ForeignKey('Account', on_delete=models.CASCADE)
> >
> >
> > class ActionLog(Log):
> > action = models.ForeignKey('Action', on_delete=models.SET_NULL)
> >
> >
> > shell:
> >
> > account = Account.objects.create()
> > action = Action.objects.create(account=account)
> > ActionLog.objects.create(account=account, action=action)
> > account.delete()
> >
> >
> > error:
> >
> > insert or update on table "myapp_log" violates foreign key constraint "myapp_log_account_id_6ea8d7a6_fk_myapp_account_id"
> > DETAIL: Key (account_id)=(11) is not present in table "myapp_account".
> >
> > But:
> > >>> Account.objects.last().id
> > 11
> >
> >
> > Why it happen? How solve it? Is a bug?
> > I am using PostgreSQL 9.3 and Django 1.9.5

I cannot reproduce the error. Here's what I get in debugsqlshell
(after I fixed the missing null=True in ActionLog.action):

In [2]: acc = Account.objects.create()
INSERT INTO "cascades_account" ("id")
VALUES (DEFAULT) RETURNING "cascades_account"."id" [2.41ms]

In [3]: action = Action.objects.create(account=acc)
INSERT INTO "cascades_action" ("account_id")
VALUES (1) RETURNING "cascades_action"."id" [20.18ms]

In [4]: log = ActionLog.objects.create(account=acc, action=action)
INSERT INTO "cascades_log" ("account_id")
VALUES (1) RETURNING "cascades_log"."id" [27.98ms]
INSERT INTO "cascades_actionlog" ("log_ptr_id",
"action_id")
VALUES (1,
1) [4.02ms]

In [5]: acc.delete()
SELECT "cascades_action"."id",
"cascades_action"."account_id"
FROM "cascades_action"
WHERE "cascades_action"."account_id" IN (1) [0.87ms]
SELECT "cascades_log"."id",
"cascades_log"."account_id",
"cascades_actionlog"."log_ptr_id",
"cascades_actionlog"."action_id"
FROM "cascades_actionlog"
INNER JOIN "cascades_log" ON ("cascades_actionlog"."log_ptr_id" = "cascades_log"."id")
WHERE "cascades_actionlog"."action_id" IN (1) [1.06ms]
SELECT "cascades_log"."id",
"cascades_log"."account_id"
FROM "cascades_log"
WHERE "cascades_log"."account_id" IN (1) [0.35ms]
DELETE
FROM "cascades_actionlog"
WHERE "cascades_actionlog"."log_ptr_id" IN (1) [0.41ms]
UPDATE "cascades_actionlog"
SET "action_id" = NULL
WHERE "cascades_actionlog"."log_ptr_id" IN (1) [0.37ms]
DELETE
FROM "cascades_action"
WHERE "cascades_action"."id" IN (1) [0.36ms]
DELETE
FROM "cascades_log"
WHERE "cascades_log"."id" IN (1) [0.37ms]
DELETE
FROM "cascades_account"
WHERE "cascades_account"."id" IN (1) [0.35ms]
Out[5]:
(4,
{'cascades.Account': 1,
'cascades.Action': 1,
'cascades.ActionLog': 1,
'cascades.Log': 1})

As you can see, everything happens as it should – the cascade
collector gathers all model instances that it's supposed to delete,
and gets rid of them in the correct order.

On Fri, Apr 22, 2016 at 08:37:48AM -0700, Neto wrote:
> Erick, *ActionLog* is inheriting *Log*. Please, pay attention before
> commenting, and see that the error has nothing to do with what you said.

I would like to remind you that we are all volunteers here, and being
condescending to the people who have shown willingness to help you
does not increase the likelihood of you getting any more help. I know
I won't be looking into this any further than I already have, because
I'm not interested in taking abuse for not finding the right solution
to your problem on the first attempt.

Best,

Michal
signature.asc

Neto

unread,
Apr 22, 2016, 9:36:31 PM4/22/16
to Django users
I discovered the problem, I have a post_delete for Action that creates a log, the problem is that this log is related to the Account, and it tries to create a log for an account being deleted, this was the conflict. Unfortunately Django does not say that the problem was in post_save.
Thank you, and Erick excuse my lack of kindness, I'm a little stressed.

Em sexta-feira, 22 de abril de 2016 01:59:25 UTC-3, Neto escreveu:
Reply all
Reply to author
Forward
0 new messages