Created https://github.com/django/django/pull/11917
This patch will print the results of the query (if it has been evaluated). I did hit one odd case while writing the tests. Essentially, if you do: queryset = SomeModel.objects.all() list(queryset) SomeModel.objects.create(...) repr(queryset) The newly created model won't appear in the repr. I believe the existing behavior will show the newly created object. I'm still not a huge fan of this repr behavior (I lean towards just displaying the SQL like RawQuerySet). I just noticed felixxm closed the original ticket. Unfortunately, I don't think I'm advertising the severity of this issue very well and most people are probably never going to encounter it (and if they do, it's probably their own fault). So to be more explicit about the problem... *How to crash your production database with Django:* 1. Use an error reporting system like Sentry 2. Have a database table with millions of rows (the more the "better") 3. Have a Django model representing the above table, with a default sort of a non-indexed field 4. Have a local variable somewhere in the stack like `queryset = HugeTable.objects.all()` (assume it doesn't get "refined down" until deeper in your code) 5. Trigger an uncaught exception 6. Your error reporting layer will call repr() on that queryset local variable. 7. repr(queryset) will trigger your database server to do SELECT ... FROM HugeTable ORDER BY NonIndexedColumn LIMIT 21 (locking it up) 8. Bonus: Trigger all of the above on all your wsgi processes In short, just call repr(BigTable.objects.all()) (where BigTable has an ordering on an non-indexed column and lots of rows) On Thursday, October 10, 2019 at 8:50:31 AM UTC-7, Matt wrote: > > repr(some_queryset) will execute the query and display some results from > the query. This is done because it's (somewhat) helpful for debugging. > > > https://github.com/django/django/blob/2a6f45e08e8cb8c7e5157915c378b453109424d2/django/db/models/query.py#L248 > > This has caused at least two people to scratch their heads about odd > queries being generated, and it crashed my production database yesterday. > > See #20393 <https://code.djangoproject.com/ticket/20393> and #30863 > <https://code.djangoproject.com/ticket/30863> > > Luke Plant has said: > > ... you have a conflict between the goal of being information rich and >> with *always* being useful for debugging. In general, automatically >> seeing the results is information rich and is useful in debugging, but >> sometimes it causes further problems. >> >> I have thought about it, and with this conflict of goals, I think we are >> going to have to err on the side of the current behaviour. It is possible >> to work around by not calling repr on QuerySets in your middleware, and >> there are too many people who will be upset (or have problems with their >> own debugging facilities) by changing this. >> > > One reason people love Django is because of its attention to things like > debug-ability. I can certainly see the argument here. However, I want to > press on the desirability of this feature. > > The argument that you can work around it by not calling repr is certainly > true, but in practice, I don't think it's reasonable. Production error > reporting tools (like Sentry and New Relic) will call repr when reporting > on exceptions. > > I see this behavior as being analogous to a file object printing the first > 21 characters of a file, which it doesn't do (for good reason, I would > imagine): > > >>> f = open("foo.py") > >>> repr(f) > "<_io.TextIOWrapper name='foo.py' mode='r' encoding='UTF-8'>" > >>> > > I think we ought to reconsider the behavior of repr on QuerySets. I'm of > the opinion that we should scrap it completely. It could be replaced by > something that generates the SQL that would be executed (although that may > be tricky), or some kind of representation of the query filter. > > Any thoughts? > -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/fef2d187-196c-43cc-8935-8b0f4779d727%40googlegroups.com.