Cách debug tệ nhất mà ai cũng từng làm: rải print() khắp nơi, chạy lại, đọc log, xoá print, lặp lại. Python có công cụ tốt hơn nhiều — pdb, trình gỡ lỗi tương tác có sẵn, không cần cài gì. Nó cho bạn dừng chương trình đúng một dòng rồi soi mọi biến đang sống, kể cả recordset ORM. Sau khi đã biết đọc log, đây là bước debug sâu hơn.
Đặt điểm dừng: chỉ một dòng
Từ Python 3.7, đặt breakpoint cực gọn — gõ breakpoint() ngay chỗ cần dừng:

Hình 1: Đặt breakpoint() trong code (thay cho import pdb; pdb.set_trace() kiểu cũ) và bảng lệnh pdb hay dùng. Lưu ý phải chạy Odoo với --workers=0: nhiều worker sẽ khiến điểm dừng rơi vào tiến trình bạn không gõ lệnh được. Thêm --limit-time-real=0 để request không bị giết khi bạn đang dừng soi biến.
Một phiên pdb thật
Đây là phiên pdb thật tôi chạy trên môi trường Odoo với db blog19: dừng lại rồi soi dữ liệu ORM bằng chính cú pháp recordset:

Hình 2: Phiên pdb thật. Tại dấu nhắc (Pdb), mọi biểu thức ORM đều chạy được: p len(cong_ty) cho 6 công ty, p cong_ty.mapped("name") in ra danh sách tên thật, p len(don_hang) cho 15 đơn hàng, p don_hang[:1].amount_total cho 2.0, p env.uid cho 1. Rồi c để chạy tiếp. Bạn soi được đúng dữ liệu thật trong luồng đang chạy — điều mà print không bao giờ làm được linh hoạt vậy.*
Các lệnh pdb cốt lõi
p <biến>/pp <biến>: in giá trị (pp = in đẹp, cho dict/list dài). Gõ được cả biểu thức:p order.partner_id.name.l(list): xem code quanh dòng đang dừng để định vị.w(where): xem ngăn xếp lời gọi — ai gọi hàm này, từ đâu.n(next): chạy hết dòng hiện tại;s(step): bước VÀO hàm được gọi.c(continue): chạy tiếp tớibreakpoint()kế;q(quit): thoát.a(args): in các tham số của hàm hiện tại.
Mẹo: gõ tên biến trần đôi khi bị nhầm với lệnh pdb (ví dụ biến tên n, c). Dùng p n cho chắc.
ipdb: bản đẹp hơn
ipdb là pdb tô màu, có tự động hoàn thành. Cài pip install ipdb rồi trỏ biến môi trường để breakpoint() tự dùng nó:
PYTHONBREAKPOINT=ipdb.set_trace odoo --workers=0 -d blog19
Không đổi một dòng code nào — cùng breakpoint(), chỉ khác trải nghiệm.
Lưu ý khi debug trong Docker
- Container phải chạy có TTY (
docker exec -it ...hoặcstdin_open: true+tty: truetrong compose) để pdb nhận bàn phím. - Với server đang chạy nền, cách gọn là dừng nó và chạy tay
docker exec -it odoo19 odoo --workers=0 ...khi cần debug. - Nhớ gỡ hết
breakpoint()trước khi commit — có checker (như pylint-odoo) bắt được cả cái này.
Nhớ ba ý
- Gõ
breakpoint()ngay dòng cần dừng — chương trình dừng lại, bạn soi mọi biến (kể cả recordset ORM) bằngp/pp. - Chạy Odoo với
--workers=0 --limit-time-real=0để pdb bắt đúng luồng và không bị giết vì quá giờ. - Lệnh cốt lõi:
p(in),l(xem code),w(ngăn xếp),n/s(chạy tiếp/bước vào),c(tiếp);ipdbcho bản đẹp hơn quaPYTHONBREAKPOINT.
Debug được Python phía sau rồi, còn phía trình duyệt thì sao? Phần sau chuyển sang debug frontend: chế độ assets dev, source map, và cách soi lỗi JavaScript của giao diện web Odoo.