我正在尝试将xlsx文件中的数据插入到mysqdl表中。我想在表中插入数据,如果主键上有重复,我想更新现有数据,否则插入。我已经编写了脚本,但我意识到这是太多的工作,使用熊猫很快。我怎样才能在熊猫中实现它?
#!/usr/bin/env python3
import pandas as pd
import sqlalchemy
engine_str = 'mysql+pymysql://admin:mypass@localhost/mydb'
engine = sqlalchemy.create_engine(engine_str, echo=False, encoding='utf-8')\
file_name = "tmp/results.xlsx"
df = pd.read_excel(file_name)
答案 0 :(得分:7)
我可以想到两个选项,但是数字1可能更清晰/更快:
1)让SQL决定更新/插入。检查this other question。您可以按照i=1
到n
的行进行迭代。在插入循环内部,您可以编写如下内容:
query = """INSERT INTO table (id, name, age) VALUES(%s, %s, %s)
ON DUPLICATE KEY UPDATE name=%s, age=%s"""
engine.execute(query, (df.id[i], df.name[i], df.age[i], df.name[i], df.age[i]))
2)定义一个python
函数,当记录存在时返回True
或False
,然后在循环中使用它:
def check_existence(user_id):
query = "SELECT EXISTS (SELECT 1 FROM your_table where user_id_str = %s);"
return list(engine.execute(query, (user_id, ) ) )[0][0] == 1
您可以在插入
之前迭代行并执行此检查另请查看可能适合您的the solution in this question和this one too。
答案 1 :(得分:1)
Pangres 是完成这项工作的工具。
此处概述: https://pypi.org/project/pangres/
<块引用>使用函数 pangres.fix_psycopg2_bad_cols 来“清理”DataFrame 中的列。
此处的代码/用法: https://github.com/ThibTrip/pangres/wiki https://github.com/ThibTrip/pangres/wiki/Fix-bad-column-names-postgres 示例代码:
# From: <https://github.com/ThibTrip/pangres/wiki/Fix-bad-column-names-postgres>
import pandas as pd
# fix bad col/index names with default replacements (empty string for '(', ')' and '%'):
df = pd.DataFrame({'test()':[0],
'foo()%':[0]}).set_index('test()')
print(df)
test() foo()%
0 0
# clean cols, index w/ no replacements
df_fixed = fix_psycopg2_bad_cols(df)
print(df_fixed)
test foo
0 0
# fix bad col/index names with custom replacements - you MUST provide replacements for '(', ')' and '%':
# reset df
df = pd.DataFrame({'test()':[0],
'foo()%':[0]}).set_index('test()')
# clean cols, index w/ user-specified replacements
df_fixed = fix_psycopg2_bad_cols(df, replacements={'%':'percent', '(':'', ')':''})
print(df_fixed)
test foopercent
0 0
只会修复/纠正一些错误的字符:
<块引用>替换 '%'、'(' 和 ')'(不会很好甚至根本不会播放的字符)
但是,它处理清理和更新插入很有用。
(ps,我知道这篇文章已经有 4 年的历史了,但在搜索“pangres upsert 确定数字插入和更新”作为顶级 SO 结果时,仍然显示在 Google 结果中,日期为 2020 年 5 月 13 日。)
>答案 2 :(得分:-1)
使用Pandas时不需要迭代。那不是更快吗?
df = pd.read_csv(csv_file,sep=';',names=['column'])
df.to_sql('table', con=con, if_exists='overwrite', index=False, chunksize=20000)