django - 在 django orm 中使用 annotate() 在 MariaDB 服务器上运行 hasrsine 公式
问题描述
嗨,我试图根据我的模型在 MariaDB 上运行 Haversine 公式,
模型是
class MeteorologicalSite(models.Model):
lat = models.DecimalField("Latitude", max_digits=17, decimal_places=15)
lon = models.DecimalField("Longitude", max_digits=17, decimal_places=15)
class Site(models.Model):
lat = models.DecimalField("Latitude", max_digits=17, decimal_places=15)
lon = models.DecimalField("Longitude", max_digits=17, decimal_places=15)
这是Haversine函数
def Haversine_formula(self, site):
from django.db.models.functions import Cos, Sin, ASin, Sqrt, Radians
lat1 = Radians(site.lat)
lon1 = Radians(site.lon)
lat2 = Radians(F("lat"))
lon2 = Radians(F("lon"))
r = 6372.8
sql_haversine_formula = 2 * r * ASin(
Sqrt(
Sin((lat1-lat2)/2)**2+
Cos(lat1)*
Cos(lat2)*
Sin((lon1 - lon2)/2)**2
)
)
MeteorologicalSite.objects.filter(radiation=True)\
.annotate(mycolumn=sql_haversine_formula)
并且它没有运行它返回<django.db.models.query.QuerySet object at 0xffff57b99ca0>
我尝试直接将 lat 和 lon 用于 1 和 2 作为 Decimal 并且它仍然不起作用
所以我知道我的问题在于我使用 annotate 的方式或我使用 sql_haversine_formula
有没有人有想法为什么这不起作用?
对不起我的英语不好
解决方案
MariaDB 支持ST_Distance_Sphere(这是 Haversine 公式)。(注意支持的版本,截至本文发表时它还算新)
使用Func你可以为 Django 包装它:
from django.db.models import Func
class Distance_Sphere(Func):
function = 'ST_DISTANCE_SPHERE'
有了这个,您应该能够在查询中使用它。
信用:来自这个答案
推荐阅读
- scenekit - SCNBillboardConstraint - 视觉调整方向,但不影响节点的 worldOrientation 属性
- c# - 无法从路径创建新位图
- .net - 如何使用 Linq 表达式从实体获取记录
- python - PyCrypto Cyphertext 长度不正确,即使只有一个字符数据
- kong - 在kong插件中获取匹配的URI
- java - 有没有办法在 Kotlin 中隐藏 Java 方法?
- c# - 确定 C# 中指定进程的磁盘 I/O 读写数据总量(以字节为单位)?
- javascript - 从分组的日期时间创建对象
- python - 在 Python 中按顺序获取查询字符串参数
- java - 从 Firebase 数据库检索时对象缺少数据