आपका HAVING
सही ढंग से संभाला जाता है, लेकिन आप इसे गलत अभिव्यक्ति दे रहे हैं। ऐसा लगता है कि आप एक स्ट्रिंग और एक पूर्णांक के बीच संबंधपरक तुलना के बाद से पायथन 2 का उपयोग कर रहे हैं
'distance' < 25
अपवाद नहीं उठाता, लेकिन False
का मूल्यांकन करता है बजाय। दूसरे शब्दों में आपकी क्वेरी
locations = db.session.query(...).having(False).all()
जो बताता है कि आपको शून्य परिणाम क्यों मिलते हैं:सभी पंक्तियों को स्पष्ट रूप से HAVING क्लॉज द्वारा फ़िल्टर किया जाता है, जैसा कि मुद्रित संस्करण में देखा गया है:
...
HAVING false = 1 -- remove all rows
एक समाधान उपयुक्त निर्माण का उपयोग करना है, जैसे कि column()
, व्यंजक उत्पन्न करने के लिए:
locations = db.session.query(...).having(column('distance') < 25).all()
आपको जटिल चयन सूची आइटम अभिव्यक्ति को select()
, जो एक सेलेक्ट स्टेटमेंट का प्रतिनिधित्व करता है। या तो text()
को लेबल करें जैसा है:
text('( 6371 * acos( cos( radians("53.6209798282177") ) * '
'cos( radians( lat ) ) * cos( radians( lng ) - radians("13.96948162900808") ) + '
'sin( radians("53.6209798282177") ) * sin( radians( lat ) ) ) ) '
'AS distance')
या मॉडल का उपयोग करके व्यंजक बनाएं:
(6371 *
func.acos(func.cos(func.radians(53.6209798282177)) *
func.cos(func.radians(Location.lat)) *
func.cos(func.radians(Location.lng) - func.radians(13.96948162900808)) +
func.sin(func.radians(53.6209798282177)) *
func.sin(func.radians(Location.lat)))).label('distance')
आप ग्रेट-सर्कल दूरी , और थोड़े से काम से आप एक हाइब्रिड विधि
Location
पर :
import math
def gc_distance(lat1, lng1, lat2, lng2, math=math):
ang = math.acos(math.cos(math.radians(lat1)) *
math.cos(math.radians(lat2)) *
math.cos(math.radians(lng2) -
math.radians(lng1)) +
math.sin(math.radians(lat1)) *
math.sin(math.radians(lat2)))
return 6371 * ang
class Location(db.Model):
...
@hybrid_method
def distance(self, lat, lng):
return gc_distance(lat, lng, self.lat, self.lng)
@distance.expression
def distance(cls, lat, lng):
return gc_distance(lat, lng, cls.lat, cls.lng, math=func)
locations = db.session.query(
Location,
Location.distance(53.6209798282177,
13.96948162900808).label('distance')).\
having(column('distance') < 25).\
order_by('distance').\
all()
ध्यान दें कि जिस तरह से आप गैर-समूह पंक्तियों को खत्म करने के लिए HAVING का उपयोग करते हैं वह पोर्टेबल नहीं है। उदाहरण के लिए Postgresql में HAVING क्लॉजकी उपस्थिति ए> ग्रुप बाय क्लॉज के बिना भी एक क्वेरी को समूहीकृत क्वेरी में बदल देता है। आप इसके बजाय एक सबक्वेरी का उपयोग कर सकते हैं:
stmt = db.session.query(
Location,
Location.distance(53.6209798282177,
13.96948162900808).label('distance')).\
subquery()
location_alias = db.aliased(Location, stmt)
locations = db.session.query(location_alias).\
filter(stmt.c.distance < 25).\
order_by(stmt.c.distance).\
all()