On Tuesday 05 March 2013, Aymeric Augustin wrote:
> On 5 mars 2013, at 12:50, Shai Berger <[email protected]> wrote:
> > At least the "delete duplicates" example I've pointed to shows, that it's
> > quite easy to write code that is correct now, under the defaults, with
> > MySql and will break with the change.
>
> http://stackoverflow.com/questions/8965391/delete-duplicate-rows-in-django-
> db
>
> In fact this code is already unsafe under MySQL with "repeatable read";
> you need "serializable" to make it safe.
>
I'm not sure what you mean by "unsafe".
Version 1: code in the question
rows = MyModel.objects.all()
for row in rows:
try:
MyModel.objects.get(photo_id=row.photo_id)
except:
row.delete()
When Django checks for a second record on get() it reads the second record, so
a repeatable-read transaction would acquire an exclusive read lock on it. This
makes it impossible for another transaction to delete the second row before
the first finishes.
Version 2: code in the first answer.
for row in MyModel.objects.all():
if MyModel.objects.filter(photo_id=row.photo_id).count() > 1:
row.delete()
To the best of my understanding, a repeatable-read transaction gets a read
lock on all records participating in a count, so again, nobody can delete the
other records before the transaction finishes.
With database-level autocommit, both versions are susceptible to having the
"other" record deleted between the read that detects it and the deletion of
the current row (deemed a redundant copy).
> The current behavior doesn't map to any common programming idiom and
> doesn't make much sense in general. The only explanation I've found is "we
> had to commit after making changes otherwise they weren't saved".
There is no argument that the change is wanted. The only issue I'm -1 on is
changing the default with no deprecation and no option to use existing
behavior.
> As a consequence, code written "unwittingly" is more likely to be incorrect
> than correct.
Still not a license to break it when it is correct, IMO.
Shai.
--
You received this message because you are subscribed to the Google Groups
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.