या SQLAlchemy में का उपयोग कर


190

मैंने डॉक्स के माध्यम से देखा है और मुझे पता नहीं लग रहा है कि SQLAlchemy में OR क्वेरी कैसे की जाती है। मैं सिर्फ यह क्वेरी करना चाहता हूं।

SELECT address FROM addressbook WHERE city='boston' AND (lastname='bulger' OR firstname='whitey')

कुछ ऐसा होना चाहिए

addr = session.query(AddressBook).filter(City == "boston").filter(????)

जवाबों:


322

से ट्यूटोरियल :

from sqlalchemy import or_
filter(or_(User.name == 'ed', User.name == 'wendy'))

72
ध्यान दें कि यह दृष्टिकोण जनरेटर का उपयोग करने का समर्थन करता है, इसलिए यदि आपके पास चीजों की एक लंबी सूची है या नहीं, तो आप कर सकते हैंfilter(or_(User.name == v for v in ('Alice', 'Bob', 'Carl')))
लुटेरे

66
@ रॉबरू की सलाह अनावश्यक रूप से अक्षम है। यदि आपके पास पहले से ही एक संग्रह है, तो आपको in_ऑपरेटर का उपयोग इस तरह करना चाहिए :filter(User.name.in_(['Alice', 'Bob', 'Carl']))
intgr

5
आह धन्यवाद मैं नहीं बारे में पता SQLAlchemy था कि फिल्टर था
robru

8
@intgr रॉकरू द्वारा दिखाया गया उदाहरण अभी भी कुशल है, यदि आप in_ के बजाय किसी अन्य ऑपरेटर का उपयोग करना चाहते हैं, उदाहरण के लिए LIKE ऑपरेटर।
ल्हासन बाज़ी

2
@intgr ओरेकल के साथ मेरा अनुभव बताता है कि "या" का एक क्रम "IN" का उपयोग करने की तुलना में अधिक तेज़ है। इसके अलावा "IN" ~ 1000 प्रविष्टियों के एक सेट तक सीमित है, जबकि "OR" नहीं है।
गा

319

SQLAlchemy बिटवाइज़ ऑपरेटर्स को ओवरलोड करता है &, |और ~इसलिए इसके बजाय बदसूरत और हार्ड-टू-रीड उपसर्ग सिंटैक्स के साथ or_()और and_()(जैसे बस्तियन के जवाब में ) आप इन ऑपरेटरों का उपयोग कर सकते हैं:

.filter((AddressBook.lastname == 'bulger') | (AddressBook.firstname == 'whitey'))

ध्यान दें कि बिटकॉइन ऑपरेटरों की पूर्वता के कारण कोष्ठक वैकल्पिक नहीं हैं ।

तो आपकी पूरी क्वेरी इस तरह दिख सकती है:

addr = session.query(AddressBook) \
    .filter(AddressBook.city == "boston") \
    .filter((AddressBook.lastname == 'bulger') | (AddressBook.firstname == 'whitey'))

8
+1, लेकिन क्या आप इसके बजाय अंतिम दो फ़िल्टर तर्क को अधिक कोष्ठक में लपेट सकते हैं और एक ही प्रभाव के लिए &उनके और पहले (एक दूसरे filterकॉल का उपयोग करने के बजाय ) के बीच का उपयोग कर सकते हैं?
संडेमन

21
@ कैफ़सैंडमैन: हाँ, आप कर सकते थे। लेकिन क्या यह अधिक पठनीय होगा? संख्या
ThiefMaster

1
जवाब में यहाँ SQLAlchemy डॉक्स के लिए एक लिंक होना बहुत अच्छा होगा!
Cheche

@ThiefMaster संयोग है कि आपके उपनाम में चोर है और आपके उदाहरण में आपके पास व्हाइटी बुलगर है ?
TheRealChx101

34

or_() OR क्वेरी घटकों की अज्ञात संख्या के मामले में फ़ंक्शन उपयोगी हो सकता है।

उदाहरण के लिए, मान लें कि हम कुछ वैकल्पिक फ़िल्टर के साथ REST सेवा बना रहे हैं, यदि कोई भी फ़िल्टर सही लौटाता है, तो उसे रिकॉर्ड वापस करना चाहिए। दूसरी तरफ, यदि पैरामीटर अनुरोध में परिभाषित नहीं किया गया था, तो हमारी क्वेरी को बदलना नहीं चाहिए। or_()फ़ंक्शन के बिना हमें ऐसा कुछ करना चाहिए:

query = Book.query
if filter.title and filter.author:
    query = query.filter((Book.title.ilike(filter.title))|(Book.author.ilike(filter.author)))
else if filter.title:
    query = query.filter(Book.title.ilike(filter.title))
else if filter.author:
    query = query.filter(Book.author.ilike(filter.author))

or_()फ़ंक्शन के साथ इसे फिर से लिखा जा सकता है:

query = Book.query
not_null_filters = []
if filter.title:
    not_null_filters.append(Book.title.ilike(filter.title))
if filter.author:
    not_null_filters.append(Book.author.ilike(filter.author))

if len(not_null_filters) > 0:
    query = query.filter(or_(*not_null_filters))

1
बहुत उपयोगी उत्तर
रे तोल

3

यह वास्तव में मददगार रहा है। यहाँ किसी भी तालिका के लिए मेरा कार्यान्वयन है:

def sql_replace(self, tableobject, dictargs):

    #missing check of table object is valid
    primarykeys = [key.name for key in inspect(tableobject).primary_key]

    filterargs = []
    for primkeys in primarykeys:
        if dictargs[primkeys] is not None:
            filterargs.append(getattr(db.RT_eqmtvsdata, primkeys) == dictargs[primkeys])
        else:
            return

    query = select([db.RT_eqmtvsdata]).where(and_(*filterargs))

    if self.r_ExecuteAndErrorChk2(query)[primarykeys[0]] is not None:
        # update
        filter = and_(*filterargs)
        query = tableobject.__table__.update().values(dictargs).where(filter)
        return self.w_ExecuteAndErrorChk2(query)

    else:
        query = tableobject.__table__.insert().values(dictargs)
        return self.w_ExecuteAndErrorChk2(query)

# example usage
inrow = {'eqmtvs_id': eqmtvsid, 'datetime': dtime, 'param_id': paramid}

self.sql_replace(tableobject=db.RT_eqmtvsdata, dictargs=inrow)

क्षमा करें, मैंने थोड़ी गलती की, निम्नलिखित पंक्ति का अनुसरण करें: क्वेरी = सेलेक्ट करें ([tableobject])। जहाँ (और _ (* फ़िल्टररगेज़))
delpozov
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.