当前位置: 首页 > 面试题库 >

Python-SqlAlchemy:通过大圆距过滤查询?

伯君浩
2023-03-14
问题内容

我正在使用Python和Sqlalchemy将纬度和经度值存储在Sqlite数据库中。我已经为Location对象创建了一个混合方法,

@hybrid_method
def great_circle_distance(self, other):
    """
    Tries to calculate the great circle distance between the two locations

    If it succeeds, it will return the great-circle distance
    multiplied by 3959, which calculates the distance in miles.

    If it cannot, it will return None.

    """
    return math.acos(  self.cos_rad_lat 
                     * other.cos_rad_lat 
                     * math.cos(self.rad_lng - other.rad_lng)
                     + self.sin_rad_lat
                     * other.sin_rad_lat
                     ) * 3959

所有类似cos_rad_latsin_rad_lat的值都是我预先计算的值,以优化计算。无论如何,当我运行以下查询时,

pq = Session.query(model.Location).filter(model.Location.great_circle_distance(loc) < 10)

我收到以下错误,

line 809, in great_circle_distance
    * math.cos(self.rad_lng - other.rad_lng)
TypeError: a float is required

当我打印的价值观self.rad_lngother.rad_lng我得到的,例如,

self.rad_lng: Location.rad_lng 
other.rad_lng: -1.29154947064

我究竟做错了什么?


问题答案:

您不能真的那样使用该math模块:

>>> c = toyschema.Contact()
>>> c.lat = 10
>>> c.lat
10
>>> import math
>>> math.cos(c.lat)
-0.83907152907645244
>>> math.cos(toyschema.Contact.lat)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: a float is required

你必须结合sqalchemy.func.*代替math.*@great_circle_distance.expression方法,对所有的那种聪明的。不幸的是,您也不能使用sqlite做到这一点;它不提供触发函数,
您可以使用PostgreSQL,也可以使用PostgreSQL,或者您可以尝试将以下函数添加到sqlite中:

编辑 它实际上不是要拼命的功能添加到sqlite的:这是 不是 测试

必须将数学函数添加到sqlite:

engine = sqlalchemy.create_engine("sqlite:///:memory:/")
raw_con = engine.raw_connection()
raw_con.create_function("cos", 1, math.cos)
raw_con.create_function("acos", 1, math.acos)

class Location(...):
    ...
    @hybrid_method
    def great_circle_distance(self, other):
        """
        Tries to calculate the great circle distance between 
        the two locations by using the Haversine formula.

        If it succeeds, it will return the Haversine formula
        multiplied by 3959, which calculates the distance in miles.

        If it cannot, it will return None.

        """
        return math.acos(  self.cos_rad_lat 
                         * other.cos_rad_lat 
                         * math.cos(self.rad_lng - other.rad_lng)
                         + self.sin_rad_lat
                         * other.sin_rad_lat
                         ) * 3959

    @great_circle_distance.expression
    def great_circle_distance(cls, other):
        return sqlalchemy.func.acos(  cls.cos_rad_lat 
                         * other.cos_rad_lat 
                         * sqlalchemy.func.cos(cls.rad_lng - other.rad_lng)
                         + cls.sin_rad_lat
                         * other.sin_rad_lat
                         ) * 3959


 类似资料:
  • 问题内容: 我刚刚开始使用SQLAlchemy。我决定使用它,因为我在sqlite查询中间使用了很多字符串表达式。 所以,这就是我的问题。我的桌子上有很多设备,每个设备都有维护级别的日期。关键是用户可以选择他想在屏幕上看到的维护级别。因此,我应该为他选择的每种维护级别组合“调整”我的SQLAlchemmy。 例如,在原始SQLite中。 SELECT * WHERE(设备IN [])和m_leve

  • 问题内容: 嗨,我想使用joinedload对查询进行过滤。但是我似乎无法使其正常工作。以下是我的示例查询 运行此命令时,它返回的行超出了我的期望。实际结果应仅返回8行。但是执行此查询后,它返回234行,这比我预期的要多 问题答案: 它不起作用的原因是(以及所有其他关系加载技术)是完全透明的。也就是说,在查询中包含a不会导致填充关系,而不会以任何其他方式影响它。您应该阅读“加入渴望的禅宗”,其开头

  • 问题内容: 我想做类似的事情: Python的标准库中是否有类似行为? 我知道在这里自己动手很容易,但是我正在寻找一种更标准的方法。 问题答案: 您可以使用filter方法: 或列表理解: 要查找单个元素,可以尝试: 尽管如果没有匹配项将引发异常,因此您可能希望将其包装在try / catch中。方括号()使之成为生成器表达式,而不是列表理解。 就我个人而言,尽管我只是使用常规的过滤器/理解并采用

  • 问题内容: 如何按字符串长度过滤? 此代码段: 给了我以下错误: 在哪里: 问题答案: 您需要使用SQL函数生成器来创建函数:

  • 问题内容: “过滤后的查询和过滤器”与“根查询和过滤器”之间有什么区别吗?例如 情况1: 情况2: 我在http://elasticsearch-users.115913.n3.nabble.com/Filtered-query-vs-using- filter-outside-td3960119.html中 找到了此讨论,但所引用的URL是404,并且解释过于简洁我。 请示教或提供指出这些区别的

  • 问题内容: 我正在尝试使用原始sqlalchemy查询将值插入Postgres11数据库。通过psql- client运行以下SQL查询时,它可以正常运行: 所有行均正确插入: 但是,如果我在sqlalchemy中创建一个引擎,并使用相同的查询在其上调用execute,它会成功运行,但不会插入任何行: 但是没有插入新行: 通过psql-client运行查询与通过sqlalchemy执行查询有何不同

  • 问题内容: 我在SQLAlchemy上没有太多经验,并且有一个我无法解决的问题。我尝试搜索,并且尝试了很多代码。这是我的课程(简化为最重要的代码): 我想查询所有母亲的phenoscore为(例如)的患者 如前所述,我尝试了很多代码,但我不明白。在我看来,合乎逻辑的解决方案是 因为,您可以在输出时访问每个元素,但是此代码不执行此操作。 是否有(直接)按关系的属性进行过滤的可能性(无需编写SQL语句