pandas迭代插入SQL Server时报'str'对象无uuid属性错误如何解决?
问题根因
你遇到的报错是以下4个代码错误共同导致的,你猜测的表头问题不是故障原因,pd.read_csv默认会将CSV第一行识别为列名,无需手动跳过:
- 遍历方法拼写错误:你调用的
itterrows()不存在,pandas逐行遍历方法正确拼写为iterrows(),错误调用会返回非预期的对象类型,触发str对象无uuid属性的报错 - 迭代返回值处理错误:
iterrows()每次迭代返回的是(行索引, 行数据Series)二元组,直接用单个变量row接收会得到元组,无法通过.列名方式取字段值 - boto3返回值key拼写错误:
get_object返回的响应体对应key是大写的Body,你写的小写body会直接触发KeyError - 缩进错误:Python要求循环体内的代码必须缩进,你写的
cursor.execute相关代码没有缩进,会触发语法错误或逻辑异常
修正后可运行代码
import boto3 import pandas as pd from io import StringIO import pymssql client = boto3.client('s3') my_bucket = 'data-staging' data_filename = 'data_pull.csv' insert_csv = client.get_object(Bucket = my_bucket, Key = data_filename) # 修正key为大写Body data_body = insert_csv["Body"] csv_string = data_body.read().decode('utf-8') data_df = pd.read_csv(StringIO(csv_string)) conn = pymssql.connect(server = 'rds_sqlserver.com', user='etl_xu',password = 'XU2014basketball', database = 'Xacation') cursor = conn.cursor() # 拆包返回的元组,修正方法拼写 for idx, row in data_df.iterrows(): # 修正缩进,用下标方式取列值比属性访问更稳妥,避免列名和Series内置属性重名 cursor.execute('''INSERT INTO xac.staging(uuid, last_name, xac_account) VALUES(?,?,?) ''', row['uuid'], row['last_name'], row['xac_account'] ) # 不要忘记提交事务,否则插入的数据不会生效 conn.commit() # 关闭连接避免资源泄漏 cursor.close() conn.close()
性能优化建议
如果你的数据量超过100行,iterrows()的遍历性能会非常差,建议用批量插入的方式,执行效率至少提升10倍:
# 把需要插入的字段直接转成元组列表 data_tuples = list(data_df[['uuid','last_name','xac_account']].itertuples(index=False, name=None)) # 一次性批量插入所有数据 cursor.executemany('''INSERT INTO xac.staging(uuid, last_name, xac_account) VALUES(?,?,?)''', data_tuples) conn.commit()
内容的提问来源于stack exchange,提问作者26Cocktails
相关产品推荐
相关产品推荐

