2012-11-06 28 views
25

Tôi đang thiết kế một API với SQLAlchemy (truy vấn MySQL) và tôi muốn buộc tất cả truy vấn của mình có tham số page_size (LIMIT) và page_number (OFFSET).Áp dụng LIMIT và OFFSET cho tất cả các truy vấn trong SQLAlchemy

Có cách nào để làm việc này với SQLAlchemy không? Có lẽ xây dựng một nhà máy của một số loại để tạo ra một đối tượng truy vấn tùy chỉnh? Hoặc có thể có một cách tốt để làm điều này với một lớp mixin?

tôi đã cố gắng điều hiển nhiên và nó đã không làm việc vì .limit() và .offset() phải được gọi sau khi tất cả các điều kiện lọc đã được áp dụng:

def q(page=0, page_size=None): 
    q = session.query(...) 
    if page_size: q = q.limit(page_size) 
    if page: q = q.offset(page*page_size) 
    return q 

Khi tôi thử sử dụng này, tôi nhận ngoại lệ:

sqlalchemy.exc.InvalidRequestError: Query.filter() being called on a Query which already has LIMIT or OFFSET applied. To modify the row-limited results of a Query, call from_self() first. Otherwise, call filter() before limit() or offset() are applied. 
+0

Xin đừng sửa một giải pháp vào câu hỏi của bạn. Thay vào đó, hãy đăng nó dưới dạng câu trả lời riêng biệt bên dưới. – Matt

Trả lời

25

Thử thêm đối số đầu tiên, bắt buộc, phải là nhóm bộ lọc truy vấn. Như vậy,

# q({'id': 5}, 2, 50) 
def q(filters, page=0, page_size=None): 
    query = session.query(...).filter_by(**filters) 
    if page_size: 
     query = query.limit(page_size) 
    if page: 
     query = query.offset(page*page_size) 
    return query 

hay,

# q(Model.id == 5, 2, 50) 
def q(filter, page=0, page_size=None): 
    query = session.query(...).filter(filter) 
    if page_size: 
     query = query.limit(page_size) 
    if page: 
     query = query.offset(page*page_size) 
    return query 
+1

Bằng cách chia nhỏ nó thành 2 phần (lấy đối tượng Truy vấn, áp dụng các bộ lọc bắt buộc), chúng tôi dựa vào nhà phát triển để nhớ gọi q() trên tất cả các truy vấn của mình. Kết quả sẽ vẫn được tạo nếu ai đó quên gọi q() trước khi gọi tất cả(). –

+0

Sau đó, bạn phải thực hiện, thay vì truy vấn, từ điển bộ lọc. Nhưng điều này sẽ hạn chế bạn một chút. – pydsigner

+1

@RobCrowell Ba năm sau, tôi tò mò nếu điều này giải quyết được vấn đề của bạn hoặc nếu bạn đã làm điều gì đó khác (trong trường hợp đó là tốt đẹp khi thấy bạn gửi câu trả lời về những gì bạn nghĩ ra)? – pydsigner

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