2016-06-22 64 views
0

我想映射一個類有一個列,這並不真正存在,但只是一個SQL查詢時綁定參數的表達式。下面的模型是我想要做的一個例子。sqlalchemy列是SQL表達式與綁定參數

class House(db.Model): 
    __tablename__ = 'houses' 

    id = db.Column(db.Integer, primary_key=True) 

    @hybrid_property 
    def distance_from_current_location(self): 
     # what to return here? 
     return self.distance_from_current_location 

    @distance_from_current_location.expression 
    def distance_from_current_location(cls, latitude, longitude): 
     return db.func.earth_distance(
      db.func.ll_to_earth(latitude, longitude), cls.earth_location) 

    # defer loading, as the raw value is pretty useless in python 
    earth_location = deferred(db.Column(EARTH)) 

然後我想通過燒瓶SQLAlchemy的查詢:

latidude = 80.20393 
longitude = -90.44380 

paged_data = \ 
    House.query \ 
     .bindparams({'latitude': latitude, 'longitude': longitude}) \ 
     .paginate(1, 20, False) 

我的問題是:

  1. 我如何做到這一點?是否有可能使用這樣的hybrid_property?
  2. 如果我可以使用hybrid_property,python方法應該返回什麼? (沒有python的方式來解釋這個,它應該只是返回任何數據庫表達式返回
  3. 緯度和經度只存在於查詢時間,並且需要爲每個查詢綁定如何在查詢時間綁定緯度和經度?在我的代碼bindparams位代碼片段我只是做了,但它說明了我想做的事情。是否有可能做到這一點?

我讀過的文檔,但無法找到任何hybrid_property或方法與示例中的綁定參數...

(也因爲這不是一個真正的列,但只是我想在我的模型上使用的東西,我不希望這觸發alembic t o爲它生成一個新列)。

謝謝!

回答

0

你不能這樣做。 distance_from_current_location也不是虛假的列,因爲它取決於查詢特定的參數。想象一下你要爲此寫一個SQL視圖;你怎麼寫這個定義? (提示:您不能)

SQLAlchemy使用標識映射模式,這意味着對於特定主鍵,整個會話中只有一個實例存在。你將如何處理查詢同一個實例,但具有不同的緯度/經度值? (從後來的查詢返回的情況下,將覆蓋那些從較早的企業之一返回。)

做到這一點,正確的方法是通過附加實體在查詢時,是這樣的:

House.query \ 
    .with_entities(House, db.func.earth_distance(db.func.ll_to_earth(latitude, longitude), House.earth_location)) \ 
    .filter(...) 

或者通過hyrbid_method (它的使用需要每一次傳遞latitudelongitude):

class House(db.Model): 
    ... 
    @hybrid_method 
    def distance_from_current_location(self, latitude, longitude): 
     # implement db.func.ll_to_earth(latitude, longitude), self.earth_location) **in Python** here 

    @distance_from_current_location.expression 
    def distance_from_current_location(cls, latitude, longitude): 
     ... 
+0

權,是啊...我想這只是術語在這裏。通過假專欄我的意思是,它不是真正的專欄,我可以做'選擇ID,earth_distance(ll_to_earth(...),...)' 我試着沿着'hybrid_property'或'hybrid_method '路徑,但是既然沒有有意義的python代碼可以寫,那麼它們都不能工作......我只想從DB獲取值。 我最後去了'with_entities()'路線,我試圖避免它,因爲當我需要處理返回的行時,它使得代碼在事物的Python方面不太方便和更加混亂。但它有效,那纔是重中之重。 – lostdorje