根据修改的时间戳替换行

时间:2017-06-06 12:04:48

标签: postgresql psycopg2

我正在寻找一种有效的方法(我可以在类似情况下重复使用)来删除已更新的行。

我的表有很多列,但重要的是:

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有空值等错误。

0 个答案:

没有答案