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

如何使用Python基于Pandas DataFrame创建Neo4j节点与关系

问题原因

你的代码存在以下几个核心错误,导致无法正常写入节点和关系:

  • 参数引用错误:在UNWIND $rows AS row的逻辑里,所有行数据都存储在row对象中,代码里写的$source、$target没有在参数字典中定义,根本取不到对应值。
  • 节点标签逻辑错误:source、target是你数据表的列名,不是节点的业务类型,你全程没有创建过带:source标签的节点,后续MATCH (s:source)永远匹配不到结果;同时节点属性写的{property: xxx}没有实际业务意义,属性键应该和存储字段对应,比如人名要存在name字段下。
  • 关系类型写死:你把关系类型固定为R_TYPE,根本没法匹配数据里lives in/born in/returns to三类不同的关系。
  • 函数传参错误:add_nodes_and_relations里调用insert_data时第一个参数传了函数自身,没有传入定义好的query语句,会直接触发参数错误。
  • 缺失返回值:Cypher语句没有返回写入计数,代码里取res[0]['total']会直接报索引错误。
  • 原始数据未清洗:target列的Utah./Canada.带多余句点,会和不带点的地名生成重复节点。
修正后实现

首先先清洗原始数据的多余标点,再写入Neo4j,以下代码默认你已经开启Neo4j预装的APOC插件(桌面版、主流云服务版Neo4j都默认自带,用来处理动态关系类型非常方便):

import pandas as pd

# 先清洗原始测试数据
df = pd.DataFrame({
    "source": ["John", "Peter", "Oscar"],
    "target": ["California", "Utah.", "Canada."],
    "relation": ["lives in", "born in", "returns to"]
})
# 去掉target列末尾多余的点
df["target"] = df["target"].str.rstrip(".")


def add_nodes_and_relations(rows, batch_size=10000):
    query = '''
            UNWIND $rows AS row
            // 合并写入源节点:人物实体,用name属性存人名作为唯一键
            MERGE (s:Person {name: trim(row.source)})
            // 合并写入目标节点:地点实体,用name属性存地名作为唯一键
            MERGE (t:Location {name: trim(row.target)})
            // 动态创建对应类型的关系,避免重复生成
            WITH s, t, row
            CALL apoc.merge.relationship(
                s, 
                replace(row.relation, " ", "_"),
                {}, 
                {}, 
                t, 
                {}
            ) YIELD rel
            // 返回当前批次写入条数供计数
            RETURN count(*) AS total
            '''
    # 修正之前的传参错误,传入query变量而不是函数自身
    return insert_data(query, rows, batch_size)


def insert_data(query, rows, batch_size = 10000):
    total = 0
    batch = 0
    result = None
    
    while batch * batch_size < len(rows):
        batch_data = rows[batch*batch_size:(batch+1)*batch_size].to_dict('records')
        res = conn.query(query, parameters = {'rows': batch_data})
        total += res[0]['total']
        batch += 1
        result = {"total_inserted": total, "batches": batch}
        print(result)
        
    return result

# 调用函数写入即可
# add_nodes_and_relations(df)
注意事项
  • Neo4j的关系名称不支持带空格,代码里用replace(row.relation, " ", "_")把空格替换为下划线,会生成LIVES_IN/BORN_IN/RETURNS_TO这类符合规范的关系类型名。
  • 如果没有安装APOC插件,可以提前在Python端把关系类型做枚举映射,通过字符串拼接生成对应Cypher即可,生产环境不要直接把未校验的外部输入拼进Cypher避免注入风险,自有测试数据可以忽略这个问题。
  • 节点标签要按实体类型划分,人物统一用:Person标签,地点统一用:Location标签,后续做查询、索引优化都会更方便,不要用数据表的列名当节点标签。
  • 所有MERGE逻辑都要优先匹配业务唯一键(这里人名、地名都用name当唯一键),避免生成重复节点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 06:18:21