python - 如何使用 Pandas 数据框更新 Postgres 表列?

标签 python pandas postgresql dataframe

我正在通过 Django(新迁移)向包含 100 多列的 Postgres 表添加一列。如何使用 pandas data_frame 中的数据更新 PostgreSQL 表中的列? Postgres SQL 的伪代码 UPDATE将是:

UPDATE wide_table wt
SET wt.z = df.z
WHERE date = 'todays_date'

这样做的原因是我正在使用 S3 中的 CSV 计算 data_frame 中的列(这是 df.z )。 Postgres update 的文档使用起来很简单,但我不确定如何通过 Django、sqlalchemy、pyodbc 等来做到这一点。

如果这有点令人费解,我深表歉意。一个小而不完整的例子是:

宽表(预更新列 z)

identifier    |      x       |      y      |      z       |      date       
foo           |      2       |      1      |     0.0      |      ...           
bar           |      2       |      8      |     0.0      |      ...      
baz           |      3       |      7      |     0.0      |      ...      
foo           |      2       |      8      |     0.0      |      ...      
foo           |      1       |      5      |     0.0      |      ...      
baz           |      2       |      8      |     0.0      |      ...      
bar           |      9       |      3      |     0.0      |      ...      
baz           |      2       |      3      |     0.0      |      ...      

示例 Python 片段

def apply_function(identifier):
    # Maps baz-> 15.0, bar-> 19.6, foo -> 10.0 for single date
    df = pd.read_csv("s3_file_path/date_file_name.csv")
    # Compute 'z' based on identifier and S3 csv
    return z

postgres_query = "Select identifier from wide_table"
df = pd.read_sql(sql=postgres_query, con=engine)
df['z'] = df.identifier.apply(apply_function)

# Python / SQL Update Logic here to update Postgres Column
???

宽表(更新后列 z)

identifier    |      x       |      y      |      z        |      date 
foo           |      2       |      1      |     10.0      |      ...     
bar           |      2       |      8      |     19.6      |      ... 
baz           |      3       |      7      |     15.0      |      ... 
foo           |      2       |      8      |     10.0      |      ... 
foo           |      1       |      5      |     10.0      |      ... 
baz           |      2       |      8      |     15.0      |      ... 
bar           |      9       |      3      |     19.6      |      ... 
baz           |      2       |      3      |     15.0      |      ... 

注意:z 中的值每天都会更改,因此简单地创建另一个表来保存这些 z 值并不是一个很好的解决方案。此外,我真的更愿意避免删除所有数据并将其添加回来。

最佳答案

遇到了类似的问题,目前接受的解决方案对我来说太慢了。我的表有 500k+ 行,我需要更新 100k+ 行。经过长时间的研究和反复试验,我得出了一个有效且正确的解决方案。

这个想法是使用 psycopg 作为你的编写器并使用一个临时表。 df 是您的 pandas 数据框,其中包含您要设置的值。

import psycopg2

conn = psycopg2.connect("dbname='db' user='user' host='localhost' password='test'")
cur = conn.cursor()

rows = zip(df.id, df.z)
cur.execute("""CREATE TEMP TABLE codelist(id INTEGER, z INTEGER) ON COMMIT DROP""")
cur.executemany("""INSERT INTO codelist (id, z) VALUES(%s, %s)""", rows)

cur.execute("""
    UPDATE table_name
    SET z = codelist.z
    FROM codelist
    WHERE codelist.id = vehicle.id;
    """)

cur.rowcount
conn.commit()
cur.close()
conn.close()

关于python - 如何使用 Pandas 数据框更新 Postgres 表列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55052395/

相关文章:

Python:从字符串访问类属性

python - Keras2.0如何连接2个 'mask_zero=True'的Embedding层?

python - mysql 从 jython 插入变量

javascript - 如何将 PostgreSQL 时间戳与 moment.js 进行比较并仅在日期基础上指定?

postgresql - 更改 Postgres.app 使用的 Postgresql 版本

python - 如何使用 map 和 reduce 在 Python 中按步骤组成函数列表

python - 过滤引号内的 df 值

python - 将某些列保留在 pandas DataFrame 中,删除其他所有内容

python - PANDAS Group通过删除标题

c - Postgres C 扩展集合 : How to detect first time aggregate function is called