如何在Python中向SQL表追加Pandas DataFrame数据不覆盖旧数据
如何在Python中向SQL表追加DataFrame数据而不覆盖旧数据?
你当前代码里的if_exists='replace'是问题的关键——这个参数会让to_sql先删除asia.rate_card表,再重新创建并插入新数据,所以旧数据就被截断了。要实现保留旧数据并追加新数据的需求,只需要把这个参数改成'append'就行。
修改后的代码
df5.to_sql('rate_card', cnx, if_exists='append', schema='asia', index=False, method='multi')
参数解释
if_exists='append':当目标表已经存在时,直接将DataFrame中的数据追加到表的末尾,完全保留原有数据。这个参数还有另外两个选项:'replace':就是你原来用的,删除原表重建并插入新数据'fail':如果表存在就抛出错误(默认行为)
- 其他参数保持不变:
schema='asia'指定表所在的模式,index=False不把DataFrame的索引作为列插入,method='multi'可以提升批量插入的效率。
注意事项
- 列一致性:新数据的列名和数据类型必须和原表完全匹配,否则会插入失败或者出现数据异常。比如你提供的新数据里
Version列有个笔误(22020-06-02应该是2020-06-02),记得先修正这类数据错误再插入。 - 重复数据/约束冲突:如果你的
rate_card表有主键或唯一约束(比如ORG_CNTY+DEST_CNTY+KG+Version作为联合唯一键),那么新数据中与旧数据重复的记录会插入失败。这时候如果需要更新重复记录而不是跳过,to_sql本身不直接支持这种"upsert"(更新或插入)操作,你可以考虑:- 先将新数据插入一个临时表
- 然后用SQL语句执行
INSERT ... ON DUPLICATE KEY UPDATE(MySQL)或者INSERT ... ON CONFLICT DO UPDATE(PostgreSQL)来实现批量更新插入
数据示例
原有表数据
| ORG_CNTY | DEST_CNTY | KG | Cost | Version |
|---|---|---|---|---|
| DE | FR | 1 | 50 | 2019-12-02 |
| DE | FR | 2 | 80 | 2019-12-02 |
| DE | IND | 2 | 65 | 2018-12-01 |
| DE | US | 1 | 70 | 2019-12-01 |
待插入新数据
| ORG_CNTY | DEST_CNTY | KG | Cost | Version |
|---|---|---|---|---|
| DE | FR | 1 | 60 | 2020-06-02 |
| DE | FR | 2 | 90 | 2020-06-02 |
| DE | IND | 1 | 55 | 2020-06-02 |
| DE | US | 1 | 80 | 2020-06-02 |
执行追加后的期望结果
| ORG_CNTY | DEST_CNTY | KG | Cost | Version |
|---|---|---|---|---|
| DE | FR | 1 | 50 | 2019-12-02 |
| DE | FR | 2 | 80 | 2019-12-02 |
| DE | IND | 2 | 65 | 2018-12-01 |
| DE | US | 1 | 70 | 2019-12-01 |
| DE | FR | 1 | 60 | 2020-06-02 |
| DE | FR | 2 | 90 | 2020-06-02 |
| DE | IND | 1 | 55 | 2020-06-02 |
| DE | US | 1 | 80 | 2020-06-02 |
内容的提问来源于stack exchange,提问作者aeapen
相关产品推荐
相关产品推荐

