【问题标题】:How to use pandas.to_sql but only add row if row doesn't exist yet如何使用 pandas.to_sql 但仅在行不存在时才添加行
【发布时间】:2020-05-11 08:32:40
【问题描述】:

我对 python 有一些经验,但对 SQL 很陌生,并尝试使用 pandas.to_sql 将表数据添加到我的数据库中,但是当我添加时,我希望它 在追加之前检查数据是否存在

这是我的 2 个数据框

>>> df0.to_markdown()
|    |   Col1 |   Col2 |
|---:|-------:|-------:|
|  0 |      0 |     00 |
|  1 |      1 |     11 |

>>> df1.to_markdown()
|    |   Col1 |   Col2 |
|---:|-------:|-------:|
|  0 |      0 |     00 |
|  1 |      1 |     11 |
|  2 |      2 |     22 |

所以这里我使用 pandas to_sql

>>> df0.to_sql(con=con, name='test_db', if_exists='append', index=False)
>>> df1.to_sql(con=con, name='test_db', if_exists='append', index=False)

这里我检查数据库文件中的数据

>>> df_out = pd.read_sql("""SELECT * FROM test_db""", con)
>>> df_out.to_markdown()
|    |   Col1 |   Col2 |
|---:|-------:|-------:|
|  0 |      0 |      0 |
|  1 |      1 |     11 |
|  2 |      0 |      0 | # Duplicate
|  3 |      1 |     11 | # Duplicate
|  4 |      2 |     22 | 

但我希望我的数据库看起来像这样,所以我不想将重复的数据添加到我的数据库中

|    |   Col1 |   Col2 |
|---:|-------:|-------:|
|  0 |      0 |      0 |
|  1 |      1 |     11 |
|  3 |      2 |     22 | 

我可以设置任何选项或添加一些代码来实现这一点吗?

谢谢!

编辑:有一些 SQL 代码只提取唯一数据,但我想要做的是首先不要将数据添加到数据库中

【问题讨论】:

  • 没有使用 pandas.to_sql 的选项。您应该使用 insted INSERT ... ON DUPLICATE KEY ...
  • 你检查过这个链接吗 - Postgres: INSERT if does not exist already
  • 回复评论#2 是的,但其中包括 SQL 代码,我正在寻找 vanilla pandas 代码 :))
  • @AnonymousAnonymous 你知道你正在向pd.to_sql写一个SQL查询字符串
  • @tidakdiinginkan 不,我没有,但我试图在pd.to_sql 之上创建一个函数,这样我就可以在不需要检查的情况下盲目地输入一堆数据,然后让函数检查代替我:)

标签: python mysql pandas pandas-to-sql


【解决方案1】:

不要使用 to_sql 一个简单的查询就可以工作

query = text(f""" INSERT INTO test_db VALUES {','.join([str(i) for i in list(df0.to_records(index=False))])} ON CONFLICT ON CONSTRAINT test_db_pkey DO NOTHING""")

self.engine.connect().execute(query)

对于每个 DataFrame 将 df0 更改为 df1

点击这些链接以获得更好的理解

【讨论】:

  • 此方法不适用于 (例如 null boolean)或 nan(例如 null string)值
【解决方案2】:

将此代码添加到您的函数中

remove_duplicate = 'EXEC remove_duplicate'
cursor.execute(remove_duplicate)
cursor.commit()

并在您的数据库中创建过程:

    CREATE PROCEDURE remove_duplicate AS
BEGIN
;WITH duplicates as (SELECT col1, col2,
                    ROW_NUMBER() OVER (PARTITION BY col1, col2, ORDER BY col1) AS number_of_duplicates
    FROM dbo.table)
    DELETE FROM duplicates WHERE number_of_duplicates > 1

END
go

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-25
    • 2017-03-20
    • 1970-01-01
    • 2016-10-19
    • 2012-04-22
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多