REEMPLAZA las filas en la tabla de base de datos mysql con pandas DataFrame

Versión de Python – 2.7.6

Versión de Pandas – 0.17.1

Versión MySQLdb – 1.2.5

En mi base de datos ( PRODUCT ), tengo una tabla ( XML_FEED ). La tabla XML_FEED es enorme (Millones de registros) Tengo un pandas.DataFrame () ( PROCESSED_DF ). El dataframe tiene miles de filas.

Ahora necesito correr esto

 REPLACE INTO TABLE PRODUCT.XML_FEED (COL1, COL2, COL3, COL4, COL5), VALUES (PROCESSED_DF.values) 

Pregunta:-

¿Hay una manera de ejecutar REPLACE INTO TABLE en pandas? Ya verifiqué pandas.DataFrame.to_sql() pero eso no es lo que necesito. No prefiero leer la tabla XML_FEED en pandas porque es muy grande.

Hasta esta versión (0.17.1) no puedo encontrar ninguna forma directa de hacer esto en pandas. Informé una solicitud de función para el mismo. Hice esto en mi proyecto ejecutando algunas consultas utilizando MySQLdb y luego utilizando DataFrame.to_sql(if_exists='append')

Suponer

1) product_id es mi clave principal en la tabla PRODUCTO

2) feed_id es mi clave principal en la tabla XML_FEED.

VERSION SIMPLE

 import MySQLdb import sqlalchemy import pandas con = MySQLdb.connect('localhost','root','my_password', 'database_name') con_str = 'mysql+mysqldb://root:my_password@localhost/database_name' engine = sqlalchemy.create_engine(con_str) #because I am using mysql df = pandas.read_sql('SELECT * from PRODUCT', con=engine) df_product_id = df['product_id'] product_id_str = (str(list(df_product_id.values))).strip('[]') delete_str = 'DELETE FROM XML_FEED WHERE feed_id IN ({0})'.format(product_id_str) cur = con.cursor() cur.execute(delete_str) con.commit() df.to_sql('XML_FEED', if_exists='append', con=engine)# you can use flavor='mysql' if you do not want to create sqlalchemy engine but it is depreciated 

Tenga en cuenta: – La syntax REPLACE [INTO] nos permite INSERT una fila en una tabla, excepto que si se produce una infracción de UNIQUE KEY (incluyendo PRIMARY KEY ), la fila anterior se elimina antes del nuevo INSERT, por lo tanto, no hay ninguna violación.

Necesitaba una solución genérica para este problema, así que aproveché la respuesta de Shiva, tal vez sea útil para otros. Esto es útil en situaciones en las que toma una tabla de una base de datos MySQL (completa o filtrada), actualiza / agrega algunas filas y desea realizar una instrucción REPLACE INTO con df.to_sql() .

Encuentra las claves primarias de la tabla, realiza una statement de eliminación en la tabla de MySQL con todas las claves del dataframe de pandas y luego inserta el dataframe en la tabla de MySQL.

 def to_sql_update(df, engine, schema, table): df.reset_index(inplace=True) sql = ''' SELECT column_name from information_schema.columns WHERE table_schema = '{schema}' AND table_name = '{table}' AND COLUMN_KEY = 'PRI'; '''.format(schema=schema, table=table) id_cols = [x[0] for x in engine.execute(sql).fetchall()] id_vals = [df[col_name].tolist() for col_name in id_cols] sql = ''' DELETE FROM {schema}.{table} WHERE 0 '''.format(schema=schema, table=table) for row in zip(*id_vals): sql_row = ' AND '.join([''' {}='{}' '''.format(n, v) for n, v in zip(id_cols, row)]) sql += ' OR ({}) '.format(sql_row) engine.execute(sql) df.to_sql(name, engine, schema=schema, if_exists='append', index=False) 

Si usa to_sql, debería poder definirlo para que reemplace los valores si existen, por lo que para una tabla llamada ‘mydb’ y un dataframe llamado ‘df’, usaría:

 df.to_sql(mydb,if_exists='replace') 

Eso debería reemplazar los valores si ya existen, pero no estoy 100% seguro de si eso es lo que está buscando.