You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sqlalchemy/Geoalchemy2实现MariaDB半径搜索返回空列表问题

解决MariaDB半径搜索返回空列表的问题

核心问题分析

你的代码用Python f-string拼接SQL表达式时,会把models.Location.lng和models.Location.lat直接转成Python对象的字符串形式,而非SQL表的列名引用,导致生成的SQL完全错误,自然查不到数据。另外,MariaDB的ST_Distance_Sphere返回单位是米,如果你的radius参数是公里数,需要先转成米(乘以1000),否则会把公里当成米判断,范围缩小1000倍,也可能返回空。

修正后的代码

from sqlalchemy import func
from sqlalchemy.orm import Session    

def get_locations_in_radius(db: Session, radius: int, lat: float, lng: float):
    # 把公里转为米(若radius以公里为单位)
    radius_meters = radius * 1000
    locations = db.query(models.Location).filter(
        func.ST_Distance_Sphere(
            # 用SQL函数构建点,直接引用列,避免f-string拼接错误
            func.ST_Point(models.Location.lng, models.Location.lat),
            func.ST_Point(lng, lat)
        ) <= radius_meters
    ).all()

    return locations

额外检查项

  • 确认数据库中lat和lng的存储顺序:确保models.Location.lng是经度、models.Location.lat是纬度,和ST_Point的参数顺序(经度在前、纬度在后)一致。
  • 可打印生成的SQL验证正确性:
    query = db.query(models.Location).filter(...)
    print(query.statement)
    
    查看输出的SQL是否正确引用了列名,而非Python对象的字符串。
  • 若MariaDB版本低于10.2.5,ST_Distance_Sphere可能不支持直接用ST_Point,可改用SQL表达式拼接WKT:
    func.ST_GeomFromText(func.concat('POINT(', models.Location.lng, ' ', models.Location.lat, ')'))
    

内容的提问来源于stack exchange,提问作者RottenSchnitzel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 11:13:16