2012-11-06 14 views
25

में सभी प्रश्नों के लिए LIMIT और ऑफ़सेट लागू करना मैं SQLAlchemy (MySQL से पूछताछ) के साथ एक एपीआई डिज़ाइन कर रहा हूं और मैं अपने सभी प्रश्नों को पेज_साइज (LIMIT) और page_number (OFFSET) पैरामीटर के लिए मजबूर करना चाहता हूं।SQLAlchemy

वहाँ SQLAlchemy के साथ ऐसा करने का एक साफ रास्ता नहीं है? शायद कस्टम क्वेरी ऑब्जेक्ट बनाने के लिए किसी प्रकार का कारखाना बनाना? या शायद मिक्सीन कक्षा के साथ ऐसा करने का एक अच्छा तरीका है?

मैं स्पष्ट बात करने की कोशिश की और यह काम नहीं किया क्योंकि के बाद सभी फिल्टर की स्थिति लागू किया गया है .limit() और .offset() बुलाया जाना चाहिए:

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 

जब मैं इस का उपयोग कर प्रयास करें, मैं

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

कृपया अपने प्रश्न में एक समाधान को संपादित नहीं करते। इसके बजाय, इसे नीचे एक अलग उत्तर के रूप में पोस्ट करें। – Matt

उत्तर

25

कोशिश पहली बार एक, आवश्यक तर्क है, जो क्वेरी फिल्टर के एक समूह होना चाहिए जोड़ने: अपवाद मिलता है। इस प्रकार,

# 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 

या,

# 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

इसे 2 टुकड़ों में तोड़कर (क्वेरी ऑब्जेक्ट प्राप्त करें, अनिवार्य फ़िल्टर लागू करें), हम डेवलपर पर भरोसा करते हैं कि वह अपने सभी प्रश्नों पर q() को कॉल करना याद रखें। अगर कोई कॉल() को कॉल करने से पहले q() को कॉल करना भूल जाता है तो परिणाम अभी भी जेनरेट किए जाएंगे। –

+0

फिर आपको एक क्वेरी, एक फ़िल्टर शब्दकोश के बजाय, लेना चाहिए। लेकिन यह आपको कुछ हद तक सीमित कर देगा। – pydsigner

+1

@RobCrowell तीन साल बाद, अगर मैं आपकी समस्या हल करता हूं या आप कुछ और करने के लिए समाप्त हो जाते हैं तो मुझे उत्सुकता है (इस मामले में यह देखना अच्छा लगेगा कि आप किस चीज के साथ आए थे इसके बारे में कोई जवाब सबमिट करें)? – pydsigner