【问题标题】:Insert or update if primary key exists into postgreSQL table with .to_sql()如果主键存在,则使用 .to_sql() 插入或更新到 postgreSQL 表中
【发布时间】:2022-11-23 02:40:17
【问题描述】:

我有一个 pandas DataFrame,它包含多个列,我想使用 .to_sql() 将它们存储到 postgreSQL 数据库中:

my_table.to_sql('table', con=engine, schema='wrhouse', if_exists='append', index=False)

我已经设置了一个主键(日期),以避免重复条目。因此,当数据库中不存在我的主键时,上述命令有效。

但是,如果该密钥存在,我会收到以下错误:

IntegrityError: (psycopg2.errors.UniqueViolation) duplicate key value violates unique constraint "table_pkey"
DETAIL:  Key (date)=(2022-07-01 00:00:00) already exists.

现在,我想做的是:

  • 用已经存在的键(日期)更新行
  • 插入一个新行以防键(日期)不存在

我查看了文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_sql.html,但我无法使用 DataFrame.to_sql() 函数找到任何选项。

此外,如果我将 if_exists='append' 参数更改为 if_exists='replace',它会删除整个表,这不是我想要的。

有什么方法可以使用 .to_sql() 函数更新/插入行吗?

【问题讨论】:

  • 使用UPSERT (INSERT .. ON CONFLICT ... DO UPDATE)。不确定如何为您的 ORM 简化它。 (人们应该只使用 SQL 而不是 1000 个不同的、大部分是半损坏的混淆层。)
  • @ErwinBrandstetter 当我显式输入 VALUES 时,这行代码有效:engine = conn.execute("INSERT INTO wrschema.table (date, first_hour, last_hour, quantity) VALUES ('2022-07-01 00:00:00', 15, 17, '250') ON CONFLICT (date) DO UPDATE SET first_hour = EXCLUDED.first_hour, last_hour = EXCLUDED.last_hour, quantity = EXCLUDED.quantity;") 但是如果我想从 DataFrame 中插入值,语法是什么?
  • 不太了解 Python / Pandas。这个相关问题应该有所帮助:stackoverflow.com/q/61366664/939860

标签: python pandas postgresql upsert pandas-to-sql


【解决方案1】:

你可以转换我的表数据框(其中包含您要发送到的新值桌子在数据库中)到numpy record array并将其添加到执行在您的评论中发挥作用^:

values = str(list(my_table.to_records(index=False)))[1:-1]

conn.execute(f"INSERT INTO wrschema.table (date, first_hour, last_hour, quantity) VALUES {values} ON CONFLICT (date) DO UPDATE SET first_hour = EXCLUDED.first_hour, last_hour = EXCLUDED.last_hour, quantity = EXCLUDED.quantity;")

(这对我有用,希望对您有所帮助!)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-31
    • 2021-02-04
    相关资源
    最近更新 更多