--
Ticket URL: <https://code.djangoproject.com/ticket/16426>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* stage: Unreviewed => Accepted
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:1>
Comment (by version2beta):
Looks to me like the problem is with the reference to {{{sub_objs}}} in
{{{django/db/models/deletion.py}}} line 166. At that point, one cannot
reference the object without generating a {{{DatabaseError: too many SQL
variables}}} error.
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:2>
Comment (by mbaechtold):
Maybe this is SQLite limition.
See "9. Maximum Number Of Host Parameters In A Single SQL Statement" on
http://www.sqlite.org/limits.html:
"To prevent excessive memory allocations, the maximum value of a host
parameter number is SQLITE_MAX_VARIABLE_NUMBER, which defaults to 999."
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:3>
Comment (by adam.hotz@…):
I have also found this problem using an SQLite database.
I am working around it using code similar to the following:
if not connection.features.supports_1000_query_parameters:
while len(Thing.objects.all()):
pks = Thing.objects.all()[0:999]
Thing.objects.filter(pk__in = pks).delete()
However this is far from optimal.
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:4>
Comment (by anonymous):
Never mind, it was easier just to recompile python and then copy the
sqlite3.dll and _sqlite.pyd files into my install. I changed the limit to
MAX_INT. A better solution would be for the sqlite3 python module to
expose the int sqlite3_limit(sqlite3*, int id, int newVal) runtime method.
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:5>
* cc: will@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:6>
Comment (by ramiro):
See also #17788.
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:7>
Comment (by anonymous):
couldn't some kind of checking be done in sqlite backend's delete() method
so it deletes the requested objects in groups < 999?
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:8>
Comment (by aaugustin):
It isn't that easy -- in particular, it could break assumptions regarding
transactions and integrity (in case of a self-referencing foreign key).
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:9>
Comment (by anonymous):
Perhaps a silly question but why does it need to list the PK of all the
things being deleted? This seems inefficient and vulnerable to limits like
the one in SQLite. Why not use SQL DELETE statements with WHERE clause?
{{{
Thing.objects.all().delete()
=> DELETE FROM Thing;
Thing.objects.filter(field='Whatsit').delete()
=> DELETE FROM Thing WHERE field='Whatsit';
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:10>
Comment (by aaugustin):
Unfortunately, this bug makes the test suite fail under SQLite since I
added a test that deletes all content types.
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:11>
Comment (by Aymeric Augustin <aymeric.augustin@…>):
In [changeset:"a892cd3191cd2e0d98756764ed7be3ad59b95850"]:
{{{
#!CommitTicketReference repository=""
revision="a892cd3191cd2e0d98756764ed7be3ad59b95850"
[1.5.x] Tweak a test to avoid hitting a limit with SQLite.
Django cannot delete more than 999 objects at a time with SQLite.
Refs #16426, #16039.
Backport of 2875b5d from master.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:13>
Comment (by Aymeric Augustin <aymeric.augustin@…>):
In [changeset:"2875b5dcab23c027d019656b08da8b911bc60711"]:
{{{
#!CommitTicketReference repository=""
revision="2875b5dcab23c027d019656b08da8b911bc60711"
Tweak a test to avoid hitting a limit with SQLite.
Django cannot delete more than 999 objects at a time with SQLite.
Refs #16426, #16039.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:12>
Comment (by akaariai):
Here is a quick attempt for fixing the limit issue:
https://github.com/akaariai/django/compare/ticket_16426
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:13>
* has_patch: 0 => 1
Comment:
I have force-updated the
https://github.com/akaariai/django/compare/ticket_16426 branch, and now
the patch is looking pretty good to me. The query-amount counting in the
added test case is ugly... But it is just ugliness in a test case.
I would not be surprised if there are delete queries which still hit the
sqlite limit - generic foreign keys, multi-inheritance etc. But, getting
this moved forward is enough IMO.
Master-only in my opinion, we can consider backpatching to 1.5.x, but lets
first see how this behaves in master.
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:14>
* cc: AkosLadanyi (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:15>
Comment (by NiGhTTraX):
Any updates regarding this issue? The patch looks good to me. Should be at
least merged into master.
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:16>
Comment (by aaugustin):
#21205 was a duplicate with an alternative patch:
https://github.com/django/django/pull/1699
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:17>
* status: new => closed
* resolution: => fixed
Comment:
In [changeset:"dfadbdac6a63dce3304dff1977b5b0a15dc2d7b5"]:
{{{
#!CommitTicketReference repository=""
revision="dfadbdac6a63dce3304dff1977b5b0a15dc2d7b5"
Fixed #16426 -- deletion of 1000+ objects with relations on SQLite
SQLite doesn't work with more than 1000 parameters in a single query.
The deletion code could generate queries that try to get related
objects for more than 1000 objects thus breaking the limit. Django now
splits the related object fetching into batches with at most 1000
parameters.
The tests and patch include some work done by Trac alias NiGhTTraX in
ticket #21205.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/16426#comment:18>