autocommit and Django

Lists: psycopg
From: Daniele Varrazzo <daniele(dot)varrazzo(at)gmail(dot)com>
To: psycopg(at)postgresql(dot)org
Subject: autocommit and Django
Date: 2011-06-14 09:42:15
Message-ID: BANLkTimtv6y8=4Yjj0dK_-6_CAVq7adP5Q@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: psycopg

Hi,

the connection.autocommit feature has created the problem shown here:

https://code.djangoproject.com/ticket/16250

I've taken a look and they have a set_autocommit method
<https://code.djangoproject.com/browser/django/trunk/django/db/backends/creation.py#L347>
implemented in a painful way: instead of being driver-specific they
just invoke some random method on the connection, and the thing is
compounds with the fact they *don't even know* there is a transaction
somehow already open. As per discussion
<http://archives.postgresql.org/psycopg/2011-05/msg00033.php>,
psycopg's set_session gives an error if invoked in a transaction.

Now, I would love to argue that Django's set_autocommit is written
with the wrong anatomical part, the bug is theirs and it's all their
problem. However, knowing the painful process they use to fix a bug I
wouldn't be surprised it would take months (see how they handled the
idle in transaction mess) and this would only be a problem for django,
postgres and psycopg users, as 2.4.2 is the version installed by
default by easy_install and friends. So I'm positive to change the
semantics of set_session/autocommit and issue an implicit rollback if
in transaction instead of raising an exception, as set_isolation_level
does.

Thoughts?

-- Daniele


From: Karsten Hilbert <Karsten(dot)Hilbert(at)gmx(dot)net>
To: psycopg(at)postgresql(dot)org
Subject: Re: autocommit and Django
Date: 2011-06-14 09:59:17
Message-ID: 20110614095917.GL2617@hermes.hilbert.loc
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: psycopg

On Tue, Jun 14, 2011 at 10:42:15AM +0100, Daniele Varrazzo wrote:

> the connection.autocommit feature has created the problem shown here:
>
> https://code.djangoproject.com/ticket/16250
>
> I've taken a look and they have a set_autocommit method
> <https://code.djangoproject.com/browser/django/trunk/django/db/backends/creation.py#L347>
> implemented in a painful way: instead of being driver-specific they
> just invoke some random method on the connection, and the thing is
> compounds with the fact they *don't even know* there is a transaction
> somehow already open. As per discussion
> <http://archives.postgresql.org/psycopg/2011-05/msg00033.php>,
> psycopg's set_session gives an error if invoked in a transaction.
>
> Now, I would love to argue that Django's set_autocommit is written
> with the wrong anatomical part, the bug is theirs and it's all their
> problem. However, knowing the painful process they use to fix a bug I
> wouldn't be surprised it would take months (see how they handled the
> idle in transaction mess) and this would only be a problem for django,
> postgres and psycopg users, as 2.4.2 is the version installed by
> default by easy_install and friends. So I'm positive to change the
> semantics of set_session/autocommit and issue an implicit rollback if
> in transaction instead of raising an exception, as set_isolation_level
> does.

IIRC it was argued by a PG developer that .autocommit = True
should *not* issue an implicit rollback. If that's so:
Please don't make psycopg2 do the "wrong" thing so others
can "fix" their problems more easily ("fix": because they
wouldn't really fix it if psycopg2 allowed the "wrong" thing
to happen).

Instead, add a state variable somewhere:

.changing_autocommit_causes_transaction_rollback

defaulting to False (the current, "correct" behaviour) which
Django can set to True if the insist on keeping to do the
"wrong" thing.

I am aware that this introduces some penalty even for other,
well-behaved code because setting autocommit will now
require checking the state of said variable.

Or else have another argument to .set_transaction():

def set_transaction(autocommit=True/False/None, autocommit_implicit_rollback=False/True):

where autocommit_implicit_rollback defaults to False.

Karsten
--
GPG key ID E4071346 @ gpg-keyserver.de
E167 67FD A291 2BEA 73BD 4537 78B9 A9F9 E407 1346


From: Federico Di Gregorio <federico(dot)digregorio(at)dndg(dot)it>
To: psycopg(at)postgresql(dot)org
Subject: Re: autocommit and Django
Date: 2011-06-14 10:02:26
Message-ID: 4DF731B2.2090808@dndg.it
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: psycopg

On 14/06/11 11:42, Daniele Varrazzo wrote:
> the connection.autocommit feature has created the problem shown here:
>
> https://code.djangoproject.com/ticket/16250
>
> I've taken a look and they have a set_autocommit method
> <https://code.djangoproject.com/browser/django/trunk/django/db/backends/creation.py#L347>
> implemented in a painful way: instead of being driver-specific they
> just invoke some random method on the connection, and the thing is
> compounds with the fact they *don't even know* there is a transaction
> somehow already open. As per discussion
> <http://archives.postgresql.org/psycopg/2011-05/msg00033.php>,
> psycopg's set_session gives an error if invoked in a transaction.
>
> Now, I would love to argue that Django's set_autocommit is written
> with the wrong anatomical part, the bug is theirs and it's all their
> problem. However, knowing the painful process they use to fix a bug I
> wouldn't be surprised it would take months (see how they handled the
> idle in transaction mess) and this would only be a problem for django,
> postgres and psycopg users, as 2.4.2 is the version installed by
> default by easy_install and friends. So I'm positive to change the
> semantics of set_session/autocommit and issue an implicit rollback if
> in transaction instead of raising an exception, as set_isolation_level
> does.
>
> Thoughts?

Yes, it is wrong. set_isolation_level() was wrong from the start but we
had to keep it that way to avoid breaking compatibility. The discussion
you linked still holds so I won't go back to sending a magic ROLLBACK.

If we don't want to wait for the #(at)§%£$! person that wrote the Django
code to fix it we can just make .autocommit a real attribute and set the
session autocommit mode when it is assigned True/False.

--
Federico Di Gregorio federico(dot)digregorio(at)dndg(dot)it
Studio Associato Di Nunzio e Di Gregorio http://dndg.it
Ma nostro di chi? Cosa abbiamo in comune io e te? -- Md


From: Federico Di Gregorio <federico(dot)digregorio(at)dndg(dot)it>
To: psycopg(at)postgresql(dot)org
Subject: Re: autocommit and Django
Date: 2011-06-14 10:09:57
Message-ID: 4DF73375.9040304@dndg.it
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: psycopg

On 14/06/11 12:02, Federico Di Gregorio wrote:
>> Thoughts?
> Yes, it is wrong. set_isolation_level() was wrong from the start but we
> had to keep it that way to avoid breaking compatibility. The discussion
> you linked still holds so I won't go back to sending a magic ROLLBACK.
>
> If we don't want to wait for the #(at)§%£$! person that wrote the Django
> code to fix it we can just make .autocommit a real attribute and set the
> session autocommit mode when it is assigned True/False.

Ok, I am completely #(at)§%£$! like a Django developer today (in fact I am
working on a project using it...).

Rewind.

Yes, it is wrong. [Rest of paragraph above...]

I think there is no way to fix this on our side. Even if we just ad an
attribute, like Karsten suggested Django code should still check it but
if they change the code they can just fix the problem without the need
to add an attribute.

federico

--
Federico Di Gregorio federico(dot)digregorio(at)dndg(dot)it
Studio Associato Di Nunzio e Di Gregorio http://dndg.it
The devil speaks truth much oftener than he's deemed.
He has an ignorant audience. -- Byron (suggested by Alice Fontana)


From: Karsten Hilbert <Karsten(dot)Hilbert(at)gmx(dot)net>
To: psycopg(at)postgresql(dot)org
Subject: Re: autocommit and Django
Date: 2011-06-14 10:15:39
Message-ID: 20110614101538.GN2617@hermes.hilbert.loc
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: psycopg

On Tue, Jun 14, 2011 at 12:09:57PM +0200, Federico Di Gregorio wrote:

> I think there is no way to fix this on our side. Even if we just add an
> attribute, like Karsten suggested Django code should still check it but
> if they change the code they can just fix the problem without the need
> to add an attribute.

Aaah, the sweet smell of sanity, reason, and logic :-)

Karsten
--
GPG key ID E4071346 @ gpg-keyserver.de
E167 67FD A291 2BEA 73BD 4537 78B9 A9F9 E407 1346


From: Daniele Varrazzo <daniele(dot)varrazzo(at)gmail(dot)com>
To: Federico Di Gregorio <federico(dot)digregorio(at)dndg(dot)it>
Cc: psycopg(at)postgresql(dot)org
Subject: Re: autocommit and Django
Date: 2011-06-14 10:23:18
Message-ID: BANLkTi=6tOcCy812_GKsXM8Bx_FD=UUoOA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: psycopg

On Tue, Jun 14, 2011 at 11:02 AM, Federico Di Gregorio
<federico(dot)digregorio(at)dndg(dot)it> wrote:

> If we don't want to wait for the #(at)§%£$! person that wrote the Django
> code to fix it we can just make .autocommit a real attribute and set the
> session autocommit mode when it is assigned True/False.

This wouldn't work as if the exception is raised it means that they
have already started a transaction, probably by setting time_zone to
chicago or something like that. The "create database" they mean to run
outside the transaction is then doomed to fail.

-- Daniele