Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

एक जटिल SQL क्वेरी को SQLAlchemy में बदलें

आपका 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()        



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySql लास्ट इंसर्ट आईडी, कनेक्टर .net

  2. Amazon ec2 पर MySQL 5.7 कैसे स्थापित करें

  3. मॉडल के लिए कोई क्वेरी परिणाम नहीं [App\Products] Laravel

  4. mysql आंशिक शब्द खोज

  5. अमान्य पैरामीटर संख्या:बाध्य चर की संख्या सिद्धांत में टोकन की संख्या से मेल नहीं खाती