Lỗi Django - truy vấn đối sánh không tồn tại


94

Cuối cùng tôi đã phát hành dự án của mình lên cấp độ sản xuất và đột nhiên tôi gặp một số vấn đề mà tôi chưa từng phải giải quyết trong giai đoạn phát triển.

Khi người dùng đăng một số hành động, đôi khi tôi gặp lỗi sau.

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

Điều thực sự làm tôi thất vọng là dự án hoạt động tốt trong môi trường cục bộ và hơn nữa, đối tượng truy vấn phù hợp KHÔNG tồn tại trong Cơ sở dữ liệu.

Bây giờ tôi đang nghi ngờ rằng người dùng đang truy cập Cơ sở dữ liệu khi nó được dành riêng cho người dùng khác, nhưng không có cách nào để chứng minh lập luận của tôi và tôi cũng không có giải pháp nào cho nó.

Có ai có loại vấn đề này trước đây không? Bất kỳ đề xuất về cách giải quyết vấn đề này?

Cảm ơn bạn rất nhiều vì sự giúp đỡ của bạn trước.

CHỈNH SỬA: Tôi đã truy vấn thủ công cơ sở dữ liệu bằng cách sử dụng cùng một thông tin được truy xuất từ ​​email lỗi máy chủ mà tôi nhận được. Tôi đã có thể đạt được mục nhập mà không có bất kỳ vấn đề nào. Hơn nữa, có vẻ như cùng một hành vi mà người dùng thực hiện hầu hết không gây ra bất kỳ vấn đề nào, mà là trong một số trường hợp (vẫn chưa được biết). Kết luận, nó chắc chắn không phải là một vấn đề với mục nhập bị thiếu trong cơ sở dữ liệu.


2
Rõ ràng, đó là một vấn đề dữ liệu: comment = Comment.objects.get(pk=comment_id)xác minh id tồn tại trong cơ sở dữ liệu
karthikr

3
"python management.py sqlall" sẽ tạo SQL tương ứng với các mô hình của bạn. Kiểm tra xem nó có tương ứng với SQL schema DB không. Nếu làm việc với PostgreSQL chẳng hạn, nó cũng có thể là một vấn đề về trình tự. Kết luận: bạn có thể cung cấp thêm thông tin về môi trường của mình (SQDB, DB, bảng tương ứng trong DB và mã trong models.py, ...) không?
Ricola3D

@ Ricola3D Xin chào Ricola, tôi hiện đang sử dụng MySql DB lưu trữ nó từ phiên bản Amazon EC2. Và tôi đang sử dụng Bình luận Django được tích hợp sẵn vào lúc này. Trong thời gian chờ đợi, tôi sẽ thử chạy lệnh sqlall mà bạn đã đề xuất. Cảm ơn bạn.
Chris P

Câu trả lời:


98

dòng của bạn làm tăng lỗi là ở đây:

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

bạn cố gắng truy cập một bình luận không tồn tại.

from django.shortcuts import get_object_or_404

comment = get_object_or_404(Comment, pk=comment_id)

Thay vì gặp lỗi trên máy chủ của bạn, người dùng của bạn sẽ nhận được mã 404 có nghĩa là anh ta cố gắng truy cập vào một tài nguyên không hiện có.

Ok đến đây tôi cho rằng bạn đã biết về điều này.

Một số người dùng (và tôi là một phần của họ) để các tab hoạt động trong thời gian dài, nếu người dùng được phép xóa dữ liệu, điều đó có thể xảy ra. Lỗi 404 có thể là một lỗi tốt hơn để xử lý lỗi tài nguyên bị xóa hơn là gửi email cho quản trị viên.

Những người dùng khác truy cập địa chỉ từ lịch sử của họ, (tương tự nếu dữ liệu đã bị xóa vì nó có thể xảy ra).


3
+1 trên các tab đang hoạt động lâu dài. 404 qua các tab cũ xảy ra với tôi rất nhiều.
Yuji 'Tomita' Tomita,

Cảm ơn bạn Chris đã gợi ý. Điều thực sự làm phiền tôi là khi tôi truy vấn cơ sở dữ liệu MySql theo cách thủ công (sử dụng thông tin lỗi mà tôi nhận được từ máy chủ), tôi đã nhấn đúng mục nhập mà không gặp bất kỳ vấn đề nào. Ngoài ra, hành động tương tự đôi khi ném ra ngoại lệ DoesNotExist nhưng hoạt động hầu hết các lần khác. Nó không có vẻ như vấn đề này với mục mất tích trong cơ sở dữ liệu :(
Chris P

Tôi có thể có ít người dùng hơn, nhưng với postgres, tôi chưa bao giờ gặp vấn đề như thế này. Chúng tôi thực sự không có nhiều thông tin, cơ sở dữ liệu của bạn không có phân cụm nô lệ / chủ? Bạn không sử dụng bộ nhớ cache trên các tập truy vấn?
christophe31

@ christophe31 Vì vậy, tôi chưa thực sự triển khai bất kỳ loại tối ưu hóa hiệu suất DB nào cũng như sao lưu các phương pháp như phân cụm nô lệ / chủ hoặc bộ nhớ đệm trên các bộ truy vấn. Tôi đoán tôi sẽ triển khai các tính năng đó và xem sự cố có tiếp diễn hay không.
Chris P

2
Ngoài ra bạn có thể thêm này trong đánh bắt: from django.db import connection, connection.connection.close(), connection.connection = Noneđể cố gắng thiết lập lại kết nối db và bắt đầu từ một cái mới.
christophe31

106

Có thể bạn không có bản ghi Nhận xét nào với khóa chính như vậy, thì bạn nên sử dụng mã này:

try:
    comment = Comment.objects.get(pk=comment_id)
except Comment.DoesNotExist:
    comment = None

3
Lựa chọn tốt nhất trong những trường hợp như vậy. Thay vì ném 404 vào người dùng, hãy bắt lỗi và hiển thị một thông báo được cấu hình sẵn đẹp mắt. Không có trái tim bỏng.
user12379095

Làm thế nào nó sẽ hoạt động ở đây? def previous_job(self): return self.get_previous_by_start_dt(brand=self.brand, status='finished') or Nonekhông biết cách triển khai thử bắt ở đây
snh_nl

24

Bạn có thể sử dụng cái này:

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

Vâng, Nếu có đối tượng cụ thể mà bạn muốn thì bạn không thể sử dụng bộ lọc vì Nó có thể trả về danh sách trống Nếu truy vấn không khớp. Và khi nó phù hợp thì bạn phải sử dụng đối tượng đầu tiên từ danh sách.
Jay Modi

3
Có lẽ đó là điểm: sử dụng bộ lọc và kiểm tra xem kết quả có không hoặc một mục nhập, thay vì tạo ra một ngoại lệ?
Mike 'Pomax' Kamermans 15/10/18

Cần lưu ý rằng nó Model.objects.filtersẽ trả về một Queryset, Model.objects.getngược lại sẽ trả về một đối tượng. Nếu đối tượng không tồn tại, đối tượng trước sẽ trả về tập truy vấn trống, đối tượng sau sẽ dẫn đến Model.DoesNotExistlỗi.
ron_g

Comment.objects.filter(pk=comment_id).first()sẽ trả lại Nonenếu không tìm thấy hồ sơ.
steezeburger

13

Bạn có thể thử cách này. chỉ cần sử dụng một hàm để lấy đối tượng của bạn

def get_object(self, id):
    try:
        return Comment.objects.get(pk=id)
    except Comment.DoesNotExist:
        return False
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.