2012-02-01 4 views
5

Tôi có đoạn code sauPython MysqlDB sử dụng cursor.rowcount với SSDictCursor trở về sai số

cur = db.cursor(cursors.SSDictCursor) 
cur.execute("SELECT * FROM large_table") 
result_count = cur.rowcount 
print result_count 

này in số 18446744073709551615 mà rõ ràng là sai. Nếu tôi xóa số cursors.SSDictCursor, số chính xác sẽ được hiển thị. Bất cứ ai có thể cho tôi biết làm thế nào tôi có thể nhận được số lượng hồ sơ trả lại trong khi vẫn giữ SSDictCursor?

Trả lời

3

Với SSDictCursor, giá trị này chỉ có thể đọc được. được xác định khi con trỏ được sử dụng hết.

Nội bộ, SSDictCursor sử dụng mysql_use_result() cho phép máy chủ bắt đầu chuyển dữ liệu trước khi hoàn tất việc mua.

+0

Cảm ơn bạn đã giảm giá. Quan tâm để giải thích? – glglgl

4

Để có được số lượng hồ sơ được trả về bởi SSDictCursor hoặc SSCursor, lựa chọn duy nhất của bạn là:

  1. Fetch kết quả toàn bộ và đếm nó sử dụng len(), mà đánh bại mục đích của việc sử dụng SSDictCursor hoặc SSCursor trong lần đầu tiên địa điểm;

  2. Đếm chính các hàng khi bạn lặp qua chúng, có nghĩa là bạn sẽ không biết số cho đến khi kết thúc (không có khả năng là thực tế); hoặc,

  3. Chạy truy vấn COUNT(*) bổ sung, riêng biệt.

Tôi khuyên bạn nên chọn tùy chọn thứ ba. Nó cực kỳ nhanh nếu tất cả những gì bạn đang làm là SELECT COUNT(*) FROM table;. Nó sẽ chậm hơn đối với một số truy vấn phức tạp hơn, nhưng với việc lập chỉ mục thích hợp, nó vẫn phải đủ nhanh cho hầu hết các mục đích.


Là một sang một bên, giá trị trả về bạn đang nhìn thấy là loại chính xác; ít nhất, như xa như MySQL C API là có liên quan.

Theo API DB Python được xác định trong PEP 249, the rowcount attribute is -1 if the rowcount of the last operation cannot be determined by the interface. @glglgl giải thích lý do tại sao rowcount không thể được xác định trong câu trả lời của họ:

Bên trong, SSDictCursor sử dụng mysql_use_result() cho phép máy chủ để bắt đầu chuyển các dữ liệu trước khi mua xong.

Nói cách khác, máy chủ không biết số lượng hàng cuối cùng sẽ tìm nạp. Khi bạn thực hiện truy vấn, MySQLdb lưu trữ giá trị trả lại là mysql_affected_rows() trong thuộc tính rowcount của con trỏ.Bởi vì số lượng là không xác định, hàm này trả -1 là một số nguyên unsigned dài dài (my_ulonglong), một loại số đó là có sẵn trong các mô-đun ctypes của thư viện tiêu chuẩn:

>>> from ctypes import c_ulonglong 
>>> n = c_ulonglong(-1) 
>>> n.value 
18446744073709551615L 

Một thay thế nhanh chóng-và-bẩn để ctypes , khi bạn biết bạn sẽ luôn luôn được làm việc với một số nguyên unsigned 64-bit, là:

>>> -1 & 0xFFFFFFFFFFFFFFFF 
18446744073709551615L 

Nó sẽ là tuyệt vời nếu MySQLdb kiểm tra giá trị trả về này và đưa cho bạn số nguyên ký bạn mong đợi để nhìn thấy, nhưng tiếc là nó không.