2016-06-22 40 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