我正在寻找一种有效的方法(我可以在类似情况下重复使用)来删除已更新的行。
我的表有很多列,但重要的是:
creation_timestamp, id, last_modified_timestamp
我的主要关键是 creation_timestamp 和 id 。但是,在创建了after和id之后,其他用户可以修改它,由 last_modified_timestamp 表示。
1)读取每日文件并添加任何新行(基于creation_timestamp和id)
2)删除具有不同last_modified_timestamp的旧行,并将其替换为最新版本。
我通常使用Pandas(python库)和pyscopg2完成大部分操作,因此我对PostgreSQL 9.6(我正在使用的数据库)并不十分熟悉。我最初的方法是将last_modified_timestamp添加到主键,然后根据最新的更改使用视图SELECT DISTINCT。然而,这似乎是“作弊”,我将浪费空间,因为我不需要保留以前的版本。
编辑:
def create_update_query(df, table=FACT_TABLE):
columns = ', '.join([f'{col}' for col in DATABASE_COLUMNS])
constraint = ', '.join([f'{col}' for col in PRIMARY_KEY])
placeholder = ', '.join([f'%({col})s' for col in DATABASE_COLUMNS])
updates = ', '.join([f'{col} = EXCLUDED.{col}' for col in DATABASE_COLUMNS])
query = f"""
INSERT INTO {table} ({columns})
VALUES ({placeholder})
ON CONFLICT ({constraint})
DO UPDATE SET {updates};"""
query.split()
query = ' '.join(query.split())
return query
def load_updates(df, connection=DATABASE):
conn = connection.get_conn()
cursor = conn.cursor()
df1 = df.where((pd.notnull(df)), None)
insert_values = df1.to_dict(orient='records')
for row in insert_values:
cursor.execute(create_update_query(df), row)
conn.commit()
cursor.close()
del cursor
conn.close()
这似乎有效。我遇到了一些问题,所以现在我循环遍历DataFrame的每一行作为字典,然后插入该行。另外,我不得不想办法用None来填充nan列,因为我的Timestamp dtypes有空值等错误。