Django error - matching query does not exist
Asked Answered
B

7

156

I finally released my project to the production level and suddenly I have some issues I never had to deal with in the development phase.

When the users posts some actions, I sometimes get the following error.

Traceback (most recent call last):

  File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 111, in get_response
    response = callback(request, *callback_args, **callback_kwargs)

  File "home/ubuntu/server/opineer/comments/views.py", line 103, in comment_expand
    comment = Comment.objects.get(pk=comment_id)

  File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py", line 131, in get
    return self.get_query_set().get(*args, **kwargs)

  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 366, in get
    % self.model._meta.object_name)

DoesNotExist: Comment matching query does not exist

What really frustrates me is that the project works fine in the local environment and furthermore, the matching query object DOES exist in the Database.

Now I am suspecting that the user is accessing the Database when it's reserved to other users, but there's no way to prove my argument nor I have any solution to it.

Does anybody had this kind of issue before? Any suggestions on how to resolve this issue?

Thank you very much for your help in advance.

EDIT: I have manually queried the database using the same information retrieved from the server error email I received. I was able to hit the entry without any issue. Furthermore, it seems like the exact same behavior the user performed does not raise any issue most of the time, but rather in some (which is yet unknown) cases. In conclusion, it definitely is not an issue with the missing entry in the database.

Basipetal answered 23/7, 2013 at 15:3 Comment(3)
Clearly, it is a data issue: comment = Comment.objects.get(pk=comment_id) verify the id exists in the databaseBeacon
"python manage.py sqlall" will generate the SQL corresponding to your models. Check if it corresponds to the DB schema SQL. If working with PostgreSQL for example, it can also be an issue of sequence. In conclusion: can you bring more information about your environment (SQDB, DB, corresponding table in DB and code in models.py, ...) ?Von
@Von Hello Ricola, I am currently using MySql DB hosting it from Amazon EC2 instance. And I am using the built in Django Comment for the time being. In the meantime, I'll try to run the sqlall command you suggested. Thank you.Basipetal
C
146

your line raising the error is here:

comment = Comment.objects.get(pk=comment_id)

you try to access a non-existing comment.

from django.shortcuts import get_object_or_404

comment = get_object_or_404(Comment, pk=comment_id)

Instead of having an error on your server, your user will get a 404 meaning that he tries to access a non existing resource.

Ok up to here I suppose you are aware of this.

Some users (and I'm part of them) let tabs running for long time, if users are authorized to delete data, it may happens. A 404 error may be a better error to handle a deleted resource error than sending an email to the admin.

Other users go to addresses from their history, (same if data have been deleted since it may happens).

Chromaticity answered 23/7, 2013 at 16:24 Comment(8)
+1 on long running tabs. 404 via old tabs happens to me a lot.Ticktock
Thank you Chris for your suggestion. What really bothers me is that when I query the MySql database manually (using the error information I received from the server) I do hit the correct entry without any issue. Also, the same action sometimes throw DoesNotExist exception but works most of the other times. It doesn't seem like the issue with the missing entry in the database :(Basipetal
I may have fewer users, but with postgres I never had this kind of problems. We really don't have many information, your database don't have slave/master clustering? You don't use cache on querysets?Chromaticity
@Chromaticity So I haven't yet really implemented any kind of DB performance optimization nor back up methods such as slave/master clustering or caching on querysets. I guess I'll implement those features and see if the problem persists.Basipetal
I thaught about it as possible problems source not as possible problems solutions ^^. As you can't reproduce the bug, I would suggest a stupid solution. try catch the error, re get in the catch after sleeping a second and logging.Chromaticity
Also you may add this in the catch: from django.db import connection, connection.connection.close(), connection.connection = None to try to reset db connection and start from a new one.Chromaticity
how to do like ` f (can_not_get Comment.objects.get(pk=comment_id)): print('not avaliable') `Jordon
@ali-al-karaawi c = Comment.objects.filter(pk=c_id).first(), then c is either your comment or None so you can if it.Chromaticity
B
181

Maybe you have no Comments record with such primary key, then you should use this code:

try:
    comment = Comment.objects.get(pk=comment_id)
except Comment.DoesNotExist:
    comment = None
Boloney answered 7/6, 2015 at 21:58 Comment(3)
Best option in such cases. Instead of throwing 404 at the user, catch the error and display a nice preconfigured message. No heart burns.Equivocal
How would it work here? def previous_job(self): return self.get_previous_by_start_dt(brand=self.brand, status='finished') or None dont know how to implement the try catch hereNan
Great answer. I have a use case where there are navigation buttons for the previous and next records by a part number. However, sometimes a part number is skipped. Catching this error and returning None is perfect.Betteann
C
146

your line raising the error is here:

comment = Comment.objects.get(pk=comment_id)

you try to access a non-existing comment.

from django.shortcuts import get_object_or_404

comment = get_object_or_404(Comment, pk=comment_id)

Instead of having an error on your server, your user will get a 404 meaning that he tries to access a non existing resource.

Ok up to here I suppose you are aware of this.

Some users (and I'm part of them) let tabs running for long time, if users are authorized to delete data, it may happens. A 404 error may be a better error to handle a deleted resource error than sending an email to the admin.

Other users go to addresses from their history, (same if data have been deleted since it may happens).

Chromaticity answered 23/7, 2013 at 16:24 Comment(8)
+1 on long running tabs. 404 via old tabs happens to me a lot.Ticktock
Thank you Chris for your suggestion. What really bothers me is that when I query the MySql database manually (using the error information I received from the server) I do hit the correct entry without any issue. Also, the same action sometimes throw DoesNotExist exception but works most of the other times. It doesn't seem like the issue with the missing entry in the database :(Basipetal
I may have fewer users, but with postgres I never had this kind of problems. We really don't have many information, your database don't have slave/master clustering? You don't use cache on querysets?Chromaticity
@Chromaticity So I haven't yet really implemented any kind of DB performance optimization nor back up methods such as slave/master clustering or caching on querysets. I guess I'll implement those features and see if the problem persists.Basipetal
I thaught about it as possible problems source not as possible problems solutions ^^. As you can't reproduce the bug, I would suggest a stupid solution. try catch the error, re get in the catch after sleeping a second and logging.Chromaticity
Also you may add this in the catch: from django.db import connection, connection.connection.close(), connection.connection = None to try to reset db connection and start from a new one.Chromaticity
how to do like ` f (can_not_get Comment.objects.get(pk=comment_id)): print('not avaliable') `Jordon
@ali-al-karaawi c = Comment.objects.filter(pk=c_id).first(), then c is either your comment or None so you can if it.Chromaticity
P
36

You can use this:

comment = Comment.objects.filter(pk=comment_id)
Phuongphycology answered 4/2, 2014 at 10:51 Comment(4)
Well, If there is specific object you want then you can not use filter as It may return empty list If query does not match. And when It matched then you gotta use first object from the list.Lentil
Presumably that's the point: use filter and test whether the result has zero or one entries, instead of generating an exception?Lachlan
Worth noting that Model.objects.filter will return a Queryset, whereas Model.objects.get will return an object. If the object doesn't exist, the former will return an empty queryset, the latter will result in a Model.DoesNotExist error.Setaceous
Comment.objects.filter(pk=comment_id).first() will return None if no records are found.Necrolatry
U
18

You may try this way. just use a function to get your object

def get_object(self, id):
    try:
        return Comment.objects.get(pk=id)
    except Comment.DoesNotExist:
        return False
Uncourtly answered 19/2, 2017 at 4:35 Comment(0)
R
0

I think the problem is that there is some data that has been passed in your dev server that wouldn't be migrated to your Production server.

The easiest thing to do will be to locate those dependencies on your production database and provide them

Rowe answered 15/6, 2022 at 11:56 Comment(2)
There are situations where dependencies may not be known until it's too late. I'll give you an example. I'm building a digital library where the detail view displays a previous and next record navigation button (for ease of reading). 99% of the time users would be expected to enter the previous and next part number, but sometimes they can't. So, there has to be a way to prevent the error. In my case, the try/except logic was ideal. The top two answers covered the question well.Betteann
I completely agree, best practice is to always prepare for errors like this, and "try and except" is a good way to do just that. My comment was about just dealing with the cause of the errorRowe
U
-2
comment = Comment.objects.get(pk=comment_id) if Comment.objects.filter(pk=comment_id).exists() else None
Upu answered 4/10, 2022 at 7:32 Comment(2)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Tyler
This results in an extra database query, which could add up quickly to heavy resource usage.Clearness
C
-3

Try this one

comment, created = Comment.objects.get_or_create(pk=comment_id)
Compile answered 2/4, 2022 at 0:43 Comment(2)
the asker doesn't need to create a commentAcyclic
Indeed. If you're querying for a record based on a condition and that condition isn't met assuming adding a record may not be appropriate at all. The top two answers have covered the question well.Betteann

© 2022 - 2024 — McMap. All rights reserved.