繁体   English   中英

使用来自 DataFrame 的数据更新 postgresql 表

[英]Update postgresql table with data from DataFrame

我有一个表,我的基础数据作为 postgresql 表,让它成为“基础数据”:

basedata:

id,name,age,height
1,john,17,185
2,nick,24,174
3,sarah,19,165

这是一个带有主键“id”的 postgresql 表。

现在我将收到一个 pandas 数据框,其中包含有关相应人员的新数据或更新数据,例如:

new_data:

id,name,age,height
17,harry,26,177
23,mary,14,145
2,nick,25,174
3,sarah,19,165

逻辑应该是:

new id -> insert into database
id already exists -> do nothing if every field is the same (like for sarah)
id already exists -> update differing fields

结果应该是:

basedata:

id,name,age,height
1,john,17,185
2,nick,25,174
3,sarah,19,165
17,harry,26,177
23,mary,14,145

我正在努力如何以最佳方式使用pythonpsycopg2做到这一点。

我需要遍历 DataFrame 并根据数据库检查每个数据行,或者是否有更优雅的方法来做到这一点? 以及如何迭代数据框的最佳方式?

您可以在 SQL 级别执行此操作,而不是遍历 DataFrame。 (由于您没有提供代码片段,因此无法从代码级别提供确切的解决方案)

  • 假设表创建如下所示,
CREATE TABLE basedata (
   id INTEGER PRIMARY KEY UNIQUE,
   name VARCHAR NOT NULL,
   age INTEGER NOT NULL,
   height INTEGER NOT NULL
);

新数据

INSERT INTO basedata (id,name, age, height)
VALUES
   (1, 'john', 17, 185),
   (2, 'nick', 24, 174),
   (3, 'sarah', 19, 165);

更新数据

INSERT INTO basedata (id, name, age, height)
VALUES
   (17, 'harry', 26, 177),
   (23, 'mary', 14, 145),
   (2, 'nick', 25, 174),
   (3, 'sarah', 19, 165)
ON CONFLICT (id)
DO NOTHING;

如需更多说明:- PostgreSQL Upsert Using INSERT ON CONFLICT 语句

使用sqlalchemy并假设数据框new_data ,流程如下:

from sqlalchemy import create_engine
engine = create_engine(my_postgresql_db_uri)
con = engine.connect()

table_name = 'basedata'

base_data = pd.read_sql(table_name, con)

data = pd.append(base_data, new_data, ignore_index=True).drop_duplicates()

data.to_sql(table_name, con, if_exists='replace')

这是未经测试的,也没有真正优化,因为每次要更新表时都必须读取表,因为pandas.to_sql 中不能有“INSERT OR UPDATE”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM