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

Python调用Neo4j Cypher传入Float变量报KeyError求助

问题排查:Python调用Neo4j point.distance时的KeyError问题

问题描述

在Python中自定义recherche_distance函数,通过Cypher查询调用Neo4j的point.distance计算距离时,传入float类型的lat和longi变量会触发KeyError: 'x '错误,但手动输入数值则运行正常。

报错信息

nosql: <V2_NoSqlDataAccess.NoSqlDataAccess object at 0x000001A283C95BE0>
<class 'float'>
<class 'float'>
lat = 45.438, longi = 4.3862
Traceback (most recent call last):
  File "c:\Datascientest\neo4j\test_projet\test.py", line 9, in <module>
    result = nsql.recherche_distance(lat, longi)
  File "c:\Datascientest\neo4j\test_projet\V2_NoSqlDataAccess.py", line 49, in recherche_distance
    cypher_query = '''
KeyError: 'x '

相关核心代码

NoSqlDataAccess类的recherche_distance方法

def recherche_distance(self, lat, longi):
        with self.driver.session() as session:
            cypher_query = '''
                MATCH (s1:Info)
                WITH point({x : toFloat(s1.latitude), y : toFloat(s1.longitude)}) AS p1, point({x:toFloat({lat}), y:toFloat({longi})}) AS p2, s1
                RETURN point.distance(p1,p2) AS Distance, s1.lieu AS Lieu ORDER BY Distance
                '''.format(lat=lat, longi=longi)
            result = session.run(cypher_query)
            return result.fetch(5)
        self.close()

调用代码

from V2_NoSqlDataAccess import NoSqlDataAccess
nsql = NoSqlDataAccess()
lat = 45.4380
longi = 4.3862
result = nsql.recherche_distance(lat, longi)

错误原因

Python的str.format()方法会把Cypher语句中定义point的{x : toFloat(s1.latitude)}识别为格式化占位符,试图查找名为x (注意后面的空格)的键,但你只传入了lat和longi两个参数,因此抛出KeyError。

解决方法

方法一:转义Cypher中的大括号

将Cypher语句里用于定义point的{}转义为{{}},保留需要替换的{lat}和{longi}:

def recherche_distance(self, lat, longi):
    with self.driver.session() as session:
        cypher_query = '''
            MATCH (s1:Info)
            WITH point({{x : toFloat(s1.latitude), y : toFloat(s1.longitude)}}) AS p1, point({{x:toFloat({lat}), y:toFloat({longi})}}) AS p2, s1
            RETURN point.distance(p1,p2) AS Distance, s1.lieu AS Lieu ORDER BY Distance
            '''.format(lat=lat, longi=longi)
        result = session.run(cypher_query)
        return result.fetch(5)
    self.close()

方法二:使用Neo4j参数化查询(推荐)

直接将参数传给session.run(),无需手动拼接字符串,避免语法冲突和注入风险:

def recherche_distance(self, lat, longi):
    with self.driver.session() as session:
        cypher_query = '''
            MATCH (s1:Info)
            WITH point({x : toFloat(s1.latitude), y : toFloat(s1.longitude)}) AS p1, point({x:toFloat($lat), y:toFloat($longi)}) AS p2, s1
            RETURN point.distance(p1,p2) AS Distance, s1.lieu AS Lieu ORDER BY Distance
            '''
        result = session.run(cypher_query, lat=lat, longi=longi)
        return result.fetch(5)
    self.close()

参数化查询是Neo4j官方推荐的方式,它会自动处理参数类型,同时避免字符串拼接带来的潜在问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 21:10:20