Galat Django - kueri yang cocok tidak ada

94

Saya akhirnya merilis proyek saya ke tingkat produksi dan tiba-tiba saya memiliki beberapa masalah yang tidak pernah saya tangani dalam tahap pengembangan.

Ketika pengguna memposting beberapa tindakan, terkadang saya mendapatkan kesalahan berikut.

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

Yang benar-benar membuat saya frustrasi adalah bahwa proyek tersebut berfungsi dengan baik di lingkungan lokal dan lebih jauh lagi, objek kueri yang cocok TIDAK ada di Database.

Sekarang saya mencurigai bahwa pengguna mengakses Database ketika itu dicadangkan untuk pengguna lain, tetapi tidak ada cara untuk membuktikan argumen saya atau saya memiliki solusi untuk itu.

Apakah ada yang pernah mengalami masalah seperti ini sebelumnya? Ada saran tentang cara mengatasi masalah ini?

Terima kasih banyak atas bantuan Anda sebelumnya.

EDIT: Saya telah menanyakan database secara manual menggunakan informasi yang sama yang diambil dari email kesalahan server yang saya terima. Saya bisa masuk tanpa masalah apa pun. Selain itu, tampaknya perilaku yang sama persis dengan yang dilakukan pengguna tidak menimbulkan masalah apa pun di sebagian besar waktu, melainkan dalam beberapa kasus (yang belum diketahui). Kesimpulannya, ini pasti bukan masalah dengan entri yang hilang dalam database.

Chris P.
sumber
2
Jelas, ini adalah masalah data: comment = Comment.objects.get(pk=comment_id)verifikasi id ada di database
karthikr
3
"python manage.py sqlall" akan menghasilkan SQL yang sesuai dengan model Anda. Periksa apakah sesuai dengan skema DB SQL. Jika bekerja dengan PostgreSQL misalnya, itu juga bisa menjadi masalah urutan. Kesimpulannya: dapatkah Anda memberikan lebih banyak informasi tentang lingkungan Anda (SQDB, DB, tabel terkait di DB dan kode di models.py, ...)?
Ricola3D
@ Ricola3D Halo Ricola, Saya sedang menggunakan MySql DB yang menghostingnya dari instans Amazon EC2. Dan saya menggunakan dibangun di Komentar Django untuk saat ini. Sementara itu, saya akan mencoba menjalankan perintah sqlall yang Anda sarankan. Terima kasih.
Chris P

Jawaban:

98

baris Anda meningkatkan kesalahan ada di sini:

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

Anda mencoba mengakses komentar yang tidak ada.

from django.shortcuts import get_object_or_404

comment = get_object_or_404(Comment, pk=comment_id)

Alih-alih mengalami kesalahan pada server Anda, pengguna Anda akan mendapatkan 404 yang berarti dia mencoba mengakses sumber daya yang tidak ada.

Ok sampai di sini saya rasa Anda sudah mengetahui hal ini.

Beberapa pengguna (dan saya bagian dari mereka) membiarkan tab berjalan untuk waktu yang lama, jika pengguna diizinkan untuk menghapus data, hal itu mungkin terjadi. Kesalahan 404 mungkin merupakan kesalahan yang lebih baik untuk menangani kesalahan sumber daya yang dihapus daripada mengirim email ke admin.

Pengguna lain pergi ke alamat dari sejarah mereka, (sama jika data telah dihapus sejak itu mungkin terjadi).

christophe31
sumber
3
+1 di tab yang berjalan lama. 404 melalui tab lama sering terjadi pada saya.
Yuji 'Tomita' Tomita
Terima kasih Chris atas saran Anda. Apa yang benar-benar mengganggu saya adalah bahwa ketika saya menanyakan database MySql secara manual (menggunakan informasi kesalahan yang saya terima dari server) saya menekan entri yang benar tanpa masalah apa pun. Selain itu, tindakan yang sama terkadang memunculkan pengecualian DoesNotExist tetapi berfungsi di sebagian besar waktu lainnya. Sepertinya tidak ada masalah dengan entri yang hilang dalam database :(
Chris P
Saya mungkin memiliki lebih sedikit pengguna, tetapi dengan postgres saya tidak pernah mengalami masalah seperti ini. Kami benar-benar tidak memiliki banyak informasi, database Anda tidak memiliki pengelompokan slave / master? Anda tidak menggunakan cache di queryset?
christophe31
@ christophe31 Jadi saya belum benar-benar menerapkan optimasi kinerja DB atau metode cadangan apa pun seperti pengelompokan slave / master atau caching di querysets. Saya kira saya akan menerapkan fitur-fitur itu dan melihat apakah masalahnya masih ada.
Chris P
2
Juga Anda dapat menambahkan ini dalam menangkap: from django.db import connection, connection.connection.close(), connection.connection = Noneuntuk mencoba untuk me-reset koneksi db dan mulai dari yang baru.
christophe31
106

Mungkin Anda tidak memiliki catatan Komentar dengan kunci utama seperti itu, maka Anda harus menggunakan kode ini:

try:
    comment = Comment.objects.get(pk=comment_id)
except Comment.DoesNotExist:
    comment = None
Dracontis
sumber
3
Pilihan terbaik dalam kasus seperti itu. Alih-alih melemparkan 404 ke pengguna, tangkap kesalahan dan tampilkan pesan bagus yang telah dikonfigurasi sebelumnya. Tidak ada hati yang terbakar.
pengguna12379095
Bagaimana cara kerjanya di sini? def previous_job(self): return self.get_previous_by_start_dt(brand=self.brand, status='finished') or Nonetidak tahu bagaimana menerapkan coba tangkap di sini
snh_nl
24

Anda dapat menggunakan ini:

comment = Comment.objects.filter(pk=comment_id)
Klang Wutcharin
sumber
Nah, jika ada objek tertentu yang Anda inginkan maka Anda tidak dapat menggunakan filter karena dapat mengembalikan daftar kosong Jika kueri tidak cocok. Dan ketika itu cocok maka Anda harus menggunakan objek pertama dari daftar.
Jay Modi
3
Agaknya itulah intinya: gunakan filter dan uji apakah hasilnya memiliki nol atau satu entri, alih-alih membuat pengecualian?
Mike 'Pomax' Kamermans
Perlu dicatat bahwa itu Model.objects.filterakan mengembalikan Queryset, sedangkan Model.objects.getakan mengembalikan objek. Jika objek tidak ada, yang pertama akan mengembalikan queryset kosong, yang terakhir akan menghasilkan Model.DoesNotExistkesalahan.
ron_g
Comment.objects.filter(pk=comment_id).first()akan kembali Nonejika tidak ada catatan yang ditemukan.
steezeburger
13

Anda dapat mencoba cara ini. cukup gunakan fungsi untuk mendapatkan objek Anda

def get_object(self, id):
    try:
        return Comment.objects.get(pk=id)
    except Comment.DoesNotExist:
        return False
Mehedi Hasan
sumber