Python向MySQL插入DataFrame数据时字符串转行属性值问题
问题根源
你手动拼接的'row.rk'、'row.age'这类元素是纯字符串,Python不会自动把这类格式的字符串解析为row对象的属性引用,所以传入execute()方法的始终是固定的字符串字面量,最终写入数据库的自然都是这些文本,而不是字段实际值。
另外你原代码还有几个隐性问题:
- SQL语句没有包裹为字符串,直接传入execute会触发语法错误
df.itertuples()默认会携带行索引作为第一个属性,不做处理会导致插入字段和值错位- 逐行调用execute插入的性能极差,数据量稍大就会出现明显卡顿
解决方案
方案1:修正现有逐行插入逻辑
用Python内置的getattr()方法,在遍历每一行的时候,通过列名字符串动态获取row对象的对应属性值即可,修正后代码如下:
# 提前定义要插入的目标列、SQL语句,不需要提前拼row.前缀 target_columns = ['rk', 'age', 'g', 'gs', 'mp', 'fg', 'fga'] insert_sql = "INSERT INTO df2(rk, age, g, gs, mp, fg, fga) VALUES (%s,%s,%s,%s,%s,%s,%s)" for row in df.itertuples(index=False): # index=False关闭默认索引返回,避免值错位 # 动态获取当前行每一列的实际值,组装为参数元组 insert_params = tuple(getattr(row, col) for col in target_columns) mycursor.execute(insert_sql, insert_params) mydb.commit()
getattr(对象, 属性名字符串)是Python标准的动态取属性的方法,效果和直接写row.rk、row.age完全一致,刚好解决你字符串无法转为属性引用的问题。
错误插入的效果参考:
方案2:推荐使用pandas原生批量写入(性能更高)
如果数据量较大,不要自己写循环逐行插入,直接用pandas内置的to_sql()方法批量写入,性能比逐行插入高几十到上百倍,代码更简洁:
# 先安装依赖:pip install pymysql sqlalchemy from sqlalchemy import create_engine # 替换为你自己的数据库连接信息:用户名、密码、地址、端口、库名 engine = create_engine("mysql+pymysql://用户名:密码@数据库IP:3306/你的库名?charset=utf8mb4") # 筛选目标列直接批量写入表 df[['rk', 'age', 'g', 'gs', 'mp', 'fg', 'fga']].to_sql( name="df2", con=engine, if_exists="append", # 追加写入,不覆盖表现有数据 index=False, # 不写入pandas行索引 method="multi" # 批量拼接插入语句,提升效率 )
内容的提问来源于stack exchange,提问作者beridzeg45
相关产品推荐
相关产品推荐

