如何将S3中的GraphML文件加载到AWS Lambda并使用NetworkX处理
问题
我有一个以GraphML格式存储在S3中的图数据,希望加载到AWS Lambda中用Python的NetworkX库处理。按照NetworkX官方文档调用read_graphml读取文件时,因为文件在S3而非本地路径,读取失败。目前已实现JSON格式文件的加载,但JSON体积增长过快,不是可行方案。
原错误代码:
import json import boto3 import networkx as nx client = boto3.client('s3') s3_bucket_name = "<bucket_name>" s3_object_key = "example.graphml" #s3_object_key = "example.json" def lambda_handler(event, context): content_object = client.get_object(Bucket=s3_bucket_name, Key=s3_object_key) file_content = content_object["Body"].read().decode('utf-8') nx.read_graphml(file_content) #json_content = json.loads(file_content) #print(json_content)
示例GraphML生成代码:
import networkx as nx G = nx.Graph() G.add_nodes_from(["A", "B", "C", "D", "E"]) G.add_edges_from([("A","C"), ("B","D"), ("B","E"), ("C", "E"), ("A", "E"), ("E", "D")]) nx.write_graphml_lxml(G, "example.graphml")
解决方案
问题核心:nx.read_graphml()若传入字符串,会将其当作本地文件路径解析,而非文件内容。直接将S3返回的二进制流转为文本模式的类文件对象即可解决。
修改后的代码:
import boto3 import networkx as nx import io client = boto3.client('s3') s3_bucket_name = "<bucket_name>" s3_object_key = "example.graphml" def lambda_handler(event, context): content_object = client.get_object(Bucket=s3_bucket_name, Key=s3_object_key) # 将S3二进制流转为UTF-8编码的文本类文件对象 file_stream = io.TextIOWrapper(content_object["Body"], encoding='utf-8') # 直接传入类文件对象加载图数据 G = nx.read_graphml(file_stream) # 后续处理示例:输出图的基础信息 print(f"节点总数: {len(G.nodes)}") print(f"边总数: {len(G.edges)}") return {"statusCode": 200, "message": "GraphML文件加载成功"}
关键说明
content_object["Body"]是StreamingBody类型的二进制流对象,无法直接被read_graphml处理(该函数需要文本模式的类文件输入)- 使用
io.TextIOWrapper完成二进制流到文本类文件对象的转换,完全符合NetworkX的读取要求 - 无需将整个文件内容读取到内存解码为字符串,既节省内存开销,也更适合处理大体积GraphML文件
内容的提问来源于stack exchange,提问作者G. Macia
相关产品推荐
相关产品推荐

