2009-07-03 25 views
52

Tôi muốn hỏi whats sự khác biệt giữaSQLAlchemy - Sự khác biệt giữa truy vấn và query.all trong cho vòng

for row in session.Query(Model1): 
    pass 

for row in session.Query(Model1).all(): 
    pass 

là lần đầu tiên bằng cách nào đó một iterator bắn phá DB của bạn với đơn truy vấn và sau này "háo hức" truy vấn toàn bộ điều như là một danh sách (như phạm vi (x) vs xrange (x))?

Trả lời

73

Không, không có sự khác biệt về lưu lượng truy cập DB. Sự khác biệt chỉ là trước đây ORM hoạt động trên mỗi hàng khi nó sắp đưa nó cho bạn, trong khi thứ hai thì ORM hoạt động trên tất cả các hàng, trước khi bắt đầu cung cấp chúng cho bạn.

Lưu ý rằng q.all() chỉ là đường cho list(q), tức là thu thập mọi thứ được tạo bởi trình tạo thành danh sách. Đây là source code cho nó, trong lớp Query (tìm def all trong nguồn liên kết):

def all(self): 
    """Return the results represented by this ``Query`` as a list. 

    This results in an execution of the underlying query. 

    """ 
    return list(self) 

... nơi self, đối tượng truy vấn, là một iterable, ví dụ: có một phương pháp __iter__.

Vì vậy, về mặt logic hai cách chính xác là giống nhau về lưu lượng truy cập DB; cả hai kết thúc bằng cách gọi số query.__iter__() để nhận trình lặp lại hàng và next() theo cách của họ thông qua nó.

Sự khác biệt thực tế là trước đây có thể bắt đầu cung cấp cho bạn hàng ngay sau khi dữ liệu của họ đến, “phát trực tuyến” kết quả DB được đặt cho bạn, ít sử dụng bộ nhớ hơn và độ trễ. Tôi không thể khẳng định chắc chắn rằng tất cả các công cụ hiện tại đều làm điều đó (tôi hy vọng họ làm được!). Trong mọi trường hợp, phiên bản thứ hai ngăn chặn hiệu quả đó, vì không có lý do chính đáng.

+0

cảm ơn, đây là câu trả lời tuyệt vời – Tom

+9

[Bài đăng này] (http://www.mail-archive.com/[email protected]/msg12443.html) đưa ra một số chi tiết về chi tiết triển khai. Câu trả lời ngắn: '__iter__' * không * tìm nạp trước tất cả các kết quả (vì lý do chính đáng), nhưng hành vi này có thể được thay đổi nếu bạn biết bạn đang làm gì. – Coquelicot

+0

Vì vậy, không có lợi thế trong việc sử dụng 'q.all()'? – dshgna

Các vấn đề liên quan