熊猫更新sql

dar*_*ool 39 python postgresql pandas

有没有办法进行SQL更新 - 从数据帧到哪里而不遍历每一行?我有一个postgresql数据库,并从数据帧更新数据库中的表我将使用psycopg2并执行以下操作:

con = psycopg2.connect(database='mydb', user='abc', password='xyz')
cur = con.cursor()

for index, row in df.iterrows():
    sql = 'update table set column = %s where column = %s'
    cur.execute(sql, (row['whatver'], row['something']))
con.commit()
Run Code Online (Sandbox Code Playgroud)

但另一方面,如果即时通讯从sql读取表或将整个数据帧写入sql(没有update-where),那么我只会使用pandas和sqlalchemy.就像是:

engine = create_engine('postgresql+psycopg2://user:pswd@mydb')
df.to_sql('table', engine, if_exists='append')
Run Code Online (Sandbox Code Playgroud)

使用to_sql进行"单线程"非常棒.是不是有类似的事情做更新 - 从熊猫到postgresql?或者是通过迭代每一行来实现它的唯一方法,就像我上面所做的那样.是不是以无效的方式遍历每一行?

Par*_*ait 38

考虑一个临时表,它可以是最终表的精确副本,每次运行时都会清除:

engine = create_engine('postgresql+psycopg2://user:pswd@mydb')
df.to_sql('temp_table', engine, if_exists='replace')

sql = """
    UPDATE final_table AS f
    SET col1 = t.col1
    FROM temp_table AS t
    WHERE f.id = t.id
"""

with engine.begin() as conn:     # TRANSACTION
    conn.execute(sql)
Run Code Online (Sandbox Code Playgroud)

  • 或者,“REPLACE INTO final_table (SELECT * FROM temp_table)”将根据 final_table 的唯一键更新所有列(并插入新列)。 (3认同)
  • @cqcn1991,您必须在每列的“UPDATE”中添加“final_col = temp_col”子句。这里仅显示一列。然后可以一次性运行该操作。 (2认同)

jef*_*ind 10

看起来您正在使用存储的一些外部数据来df满足更新数据库表的条件.如果有可能为什么不只是做一行的SQL更新?

如果您正在使用一个小型数据库(将整个数据加载到python数据帧对象并不会导致您死亡),那么您可以在使用后加载数据帧后有条件地更新数据帧read_sql.然后,您可以使用关键字arg if_exists="replace"将DB表替换为新更新的表.

df = pandas.read_sql("select * from your_table;", engine)

#update information (update your_table set column = "new value" where column = "old value")
#still may need to iterate for many old value/new value pairs
df[df['column'] == "old value", "column"] = "new value"

#send data back to sql
df.to_sql("your_table", engine, if_exists="replace")
Run Code Online (Sandbox Code Playgroud)

Pandas是一个功能强大的工具,有限的SQL支持起初只是一个小功能.随着时间的推移,人们正试图将熊猫作为他们唯一的数据库接口软件.我不认为大熊猫曾经是数据库交互的终极目标,但是有很多人一直在研究新功能.请参阅:https://github.com/pandas-dev/pandas/issues

  • 如果 to_sql() 方法的属性设置为“ if_exists='replace' ”,它将删除该表。所以在这个例子中,是的。请参阅:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_sql.html (2认同)
  • 这样做的问题是它还必须删除所有依赖的视图。 (2认同)
  • 删除 if_exists = "replace" 的事实还意味着表的约束和数据库中设置的数据类型将丢失并自动替换,这在大多数情况下不是理想的行为。 (2认同)

fir*_*ynx 5

到目前为止,我还没有看到可以以任何可扩展的方式使用 pandas sql 连接器来更新数据库数据的情况。建立一个似乎是个好主意,但实际上,对于运营工作,它只是不能扩展。

我建议使用将整个数据帧转储为 CSV

df.to_csv('filename.csv', encoding='utf-8')
Run Code Online (Sandbox Code Playgroud)

然后使用COPY for PostgreSQL 或LOAD DATA INFILE for MySQL将 CSV 加载到数据库中。

如果在 Pandas 操作数据时不对相关表进行其他更改,则可以将其加载到表中。

如果存在并发问题,则必须将数据加载到临时表中,然后用于更新主表。

在后一种情况下,您的主表需要有一个日期时间,它告诉您最新修改的时间,以便您可以确定您的 Pandas 更改是最新的还是应该保留数据库更改。