Pandas actualizar sql

¿Hay alguna forma de realizar una actualización de SQL desde un dataframe sin iterar a través de cada línea? Tengo una base de datos postgresql y para actualizar una tabla en la base de datos desde un dataframe usaría psycopg2 y haría algo como:

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() 

Pero, por otro lado, si estoy leyendo una tabla desde SQL o escribiendo un dataframe completo en SQL (sin actualización de dónde), solo usaría pandas y sqlalchemy. Algo como:

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

Es genial tener un ‘one-liner’ usando to_sql. ¿No hay algo similar para hacer una actualización, desde pandas hasta postgresql? O es la única forma de hacerlo iterando a través de cada fila como lo he hecho anteriormente. ¿No es iterativo a través de cada fila una forma ineficiente de hacerlo?

Considere una tabla temporal que sería una réplica exacta de su tabla final, limpiada con cada ejecución:

 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) 

Parece que está utilizando algunos datos externos almacenados en df para las condiciones en la actualización de su tabla de base de datos. Si es posible, ¿por qué no solo hacer una actualización de sql de una línea?

Si está trabajando con una base de datos pequeña (donde cargar los datos completos en el objeto de dataframe de Python no lo va a matar), definitivamente puede actualizar el dataframe de forma condicional después de cargarlo con read_sql . Luego, puede usar una palabra clave arg if_exists="replace" para reemplazar la tabla de base de datos con la nueva tabla actualizada.

 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") 

Pandas es una herramienta poderosa, donde el soporte limitado de SQL era solo una pequeña característica al principio. A medida que pasa el tiempo, las personas están tratando de usar pandas como su único software de interfaz de base de datos. No creo que los pandas estuvieran destinados a ser el fin de la interacción con la base de datos, pero hay muchas personas trabajando en nuevas funciones todo el tiempo. Consulte: https://github.com/pandas-dev/pandas/issues

Hasta ahora no he visto un caso en el que el conector de pandas sql pueda utilizarse de forma escalable para actualizar los datos de la base de datos. Puede parecer una buena idea construir una, pero en realidad, para el trabajo operativo simplemente no se puede escalar.

Lo que recomendaría es volcar todo el dataframe como CSV usando

 df.to_csv('filename.csv', encoding='utf-8') 

Luego, cargue el CSV en la base de datos utilizando COPY para PostgreSQL o LOAD DATA INFILE para MySQL.

Si no realiza otros cambios en la tabla en cuestión mientras los pandas están manipulando los datos, puede cargarlos en la tabla.

Si hay problemas de concurrencia, tendrá que cargar los datos en una tabla de etapas que luego utilizará para actualizar su tabla principal.

En el último caso, su tabla principal debe tener una fecha y hora que le indique cuándo se realizó la última modificación para que pueda determinar si los cambios de pandas son los más recientes o si los cambios de la base de datos deberían permanecer.

Me preguntaba por qué no actualiza el df primero en función de su ecuación y luego almacena el df en la base de datos, podría usar if_exists = ‘replace’, para almacenar en la misma tabla.

Si necesita actualizar un panda basado en múltiples condiciones para simular los SQL:

 UPDATE table WHERE A > 7 AND B > 69 

Simplemente puedes usar .loc

 >>> df ABC 0 2 40 800 1 1 90 600 2 6 80 700 3 1998 70 55 4 1 90 300 5 7 80 700 6 4 20 300 7 1998 20 2 8 7 10 100 9 1998 60 2 >>> df.loc[(df['A'] > 7) & (df['B'] > 69) , 'C'] = 75 

Esto establecerá ‘C’ = 75 donde ‘A’> 7 y ‘B’> 69