【发布时间】:2021-03-13 19:33:39
【问题描述】:
我有两个pandasDataFrames:
df1 来自数据库 A,连接参数为 {"host":"hostname_a","port": "5432", "dbname":"database_a", "user": "user_a", "password": "secret_a"}。 key 列是主键。
df1:
| | key | create_date | update_date |
|---:|------:|:-------------|:--------------|
| 0 | 57247 | 1976-07-29 | 2018-01-21 |
| 1 | 57248 | | 2018-01-21 |
| 2 | 57249 | 1992-12-22 | 2016-01-31 |
| 3 | 57250 | | 2015-01-21 |
| 4 | 57251 | 1991-12-23 | 2015-01-21 |
| 5 | 57262 | | 2015-01-21 |
| 6 | 57263 | | 2014-01-21 |
df2 来自数据库 B,连接参数为 {"host": "hostname_b","port": "5433", "dbname":"database_b", "user": "user_b", "password": "secret_b"}。 id 列是主键(这些值最初与df1 中key 列中的值相同;只是对df1 主键列的重命名)。
df2:
| | id | create_date | update_date | user |
|---:|------:|:-------------|:--------------|:------|
| 0 | 57247 | 1976-07-29 | 2018-01-21 | |
| 1 | 57248 | | 2018-01-21 | |
| 2 | 57249 | 1992-12-24 | 2020-10-11 | klm |
| 3 | 57250 | 2001-07-14 | 2019-21-11 | ptl |
| 4 | 57251 | 1991-12-23 | 2015-01-21 | |
| 5 | 57262 | | 2015-01-21 | |
| 6 | 57263 | | 2014-01-21 | |
请注意,df2 中的 row[2] 和 row[3] 的 update_date 值(分别为 2020-10-11 和 2019-21-11)比 df1 中的对应值(其中 id = @ 987654349@) 因为他们的creation_date 已被修改(由给定的用户)。
我想更新 df1 的行(即具体而言;create_date 和 update_date 值),其中 df2 中的 update_date 比 df1 中的原始值更新(对于相同的主键)。
这就是我目前解决这个问题的方法,使用sqlalchemy 和psycopg2 + .to_sql() 方法pandas'DataFrame:
import psycopg2
from sqlalchemy import create_engine
connector = psycopg2.connect(**database_parameters_dictionary)
engine = create_engine('postgresql+psycopg2://', creator=connector)
df1.update(df2) # 1) maybe there is something better to do here?
with engine.connect() as connection:
df1.to_sql(
name="database_table_name",
con=connection,
schema="public",
if_exists="replace", # 2) maybe there is also something better to do here?
index=True
)
我的问题是,根据文档,if_exists 参数只能做三件事:
if_exists{‘fail’, ‘replace’, ‘append’},默认‘fail’
因此,要更新这两行,我必须;
1) 在df1 上使用.update() 方法,使用df2 作为参数,以及
2) 替换.to_sql() 方法中的整个表,意思是“drop+recreate”。
由于表格非常大(超过 500'000 个条目),我觉得这需要很多不必要的工作!
我怎样才能有效地只更新这两个新更新的行?我是否必须生成一些自定义 SQL 查询来比较每一行的日期,并且只取那些真正改变的日期?但是在这里,我有直觉,循环遍历所有行以比较更新日期将花费“很多”时间。如何更有效地做到这一点? (如果两个表在同一个主机/数据库上,在纯 SQL 中会更容易,但不幸的是,情况并非如此)。
【问题讨论】:
标签: python-3.x pandas postgresql dataframe sqlalchemy