python - 如何使用 pandas 数据框有效地更新 mysql 表?
问题描述
我正在使用 Airflow PythonOperator 进行 ETL 以更新 SCD1 维度表 ( dim_user
)。
mysql维表的结构:
| user_key | open_id | gender | nickname | mobile | load_time | updated_at |
|----------|---------------------|--------|----------|-------------|---------------------|---------------------|
| 117 | ohwv90JTgZSn******* | 2 | ABC | ************| 2019-05-24 10:12:44 | 2019-05-23 19:00:43 |
在 python 脚本中,我有一个相同的结构(除了 user_key 和 load_time 列) pandas dataframe df_users_updated
。
现在我想在open_id
字段匹配的条件下更新 mysql 表:
# database connection
conn = create_engine(db_conn_str)
# update the rows with a for loop
for index, row in df_users_updated.iterrows():
info = dict(row)
conn.execute('update dim_user set gender=%s, nickname=%s, mobile=%s, updated_at=%s where open_id=%s',
(info['gender'], info['nickname'], info['mobile'], info['updated_at'], info['open_id']))
conn.dispose()
问题是我在 df_users_updated 中只有 1000 行,执行这些更新查询需要 10 多分钟。
有一个更好的方法吗?
解决方案
根据我的经验,有一些技巧可以提高性能。
- 使用
mysqlclient
库,cursor.executemany(sql, params)
方法 - 使用
tuple
参数类型 - 在 where 字段上使用索引。
推荐阅读
- r - 如何使用 agrep 获得模糊字符串匹配的精确通用“max.distance”值?
- angularjs - 在一个按钮上禁用多个元素
- jenkins - 如何在 Bitbucket 中自定义 Jenkins 设置的构建消息
- php - Laravel 将请求输入从字符串更改为数组
- javascript - 过滤对象键,在日期之间
- c# - 如何从kafka消息总线推送通知消费者
- adobe-indesign - 在 Adobe Indesign 中创建上下文菜单
- django - Django“ValueError:源代码字符串不能包含空字节”
- python - 根据子列表中项目的顺序将列表列表转换为字典列表
- angular - Angular cli - 组件样式的输出