web-dev-qa-db-fra.com

Ecrire dans la base de données MySQL avec des pandas utilisant SQLAlchemy, to_sql

essayer d'écrire pandas dataframe sur la table MySQL en utilisant to_sql. Auparavant utilisé flavour = 'mysql', il sera toutefois amorti à l'avenir et souhaitait commencer la transition vers l'utilisation du moteur SQLAlchemy.

exemple de code:

import pandas as pd
import mysql.connector
from sqlalchemy import create_engine

engine = create_engine('mysql+mysqlconnector://[user]:[pass]@[Host]:[port]/[schema]', echo=False)
cnx = engine.raw_connection()
data = pd.read_sql('SELECT * FROM sample_table', cnx)
data.to_sql(name='sample_table2', con=cnx, if_exists = 'append', index=False)

La lecture fonctionne bien mais le to_sql a une erreur:

DatabaseError: L'exécution a échoué sur SQL 'SELECT nom FROM sqlite_master WHERE type =' table 'AND nom = ?;': Nombre d'arguments incorrect lors du formatage de chaîne

Pourquoi a-t-il l'air d'essayer d'utiliser sqlite? Quelle est l'utilisation correcte d'une connexion sqlalchemy avec mysql et plus précisément mysql.connector?

J'ai également essayé de passer le moteur comme connexion, ce qui m'a donné une erreur en faisant référence à aucun objet curseur.

data.to_sql(name='sample_table2', con=engine, if_exists = 'append', index=False)
>>AttributeError: 'Engine' object has no attribute 'cursor'
40
AsAP_Sherb

Utiliser le moteur à la place de raw_connection () a fonctionné:

import pandas as pd
import mysql.connector
from sqlalchemy import create_engine

engine = create_engine('mysql+mysqlconnector://[user]:[pass]@[Host]:[port]/[schema]', echo=False)
data.to_sql(name='sample_table2', con=engine, if_exists = 'append', index=False)

pas clair pourquoi, quand j'ai essayé hier, il m'a donné l'erreur précédente

56
AsAP_Sherb

Sinon, utilisez le paquet pymysql ...

import pymysql
from sqlalchemy import create_engine
cnx = create_engine('mysql+pymysql://[user]:[pass]@[Host]:[port]/[schema]', echo=False)

data = pd.read_sql('SELECT * FROM sample_table', cnx)
data.to_sql(name='sample_table2', con=cnx, if_exists = 'append', index=False)
6
openwonk

En utilisant pymysql et sqlalchemy, cela fonctionne pour Pandas v0.22: 

import pandas as pd
import pymysql
from sqlalchemy import create_engine

user = 'yourUserName'
passw = 'password'
Host =  'hostName'  # either localhost or ip e.g. '172.17.0.2' or hostname address 
port = 3306 
database = 'dataBaseName'

mydb = create_engine('mysql+pymysql://' + user + ':' + passw + '@' + Host + ':' + str(port) + '/' + database , echo=False)

directory = r'directoryLocation'  # path of csv file
csvFileName = 'something.csv'

df = pd.read_csv(os.path.join(directory, csvFileName ))

df.to_sql(name=csvFileName[:-4], con=mydb, if_exists = 'replace', index=False)

"""
if_exists: {'fail', 'replace', 'append'}, default 'fail'
     fail: If table exists, do nothing.
     replace: If table exists, drop it, recreate it, and insert data.
     append: If table exists, insert data. Create if does not exist.
"""
3
DougR

Je sais que le mot SQLAlchemy est inclus dans le titre de la question. Cependant, je vois dans les questions et réponses la nécessité d'importer pymysql ou mysql.connector, et il est également possible de faire le travail avec pymysql sans appeler SQLAlchemy.

import pymysql
user = 'root'
passw = 'my-secret-pw-for-mysql-12ud' # In previous posts variable "pass"
Host =  '172.17.0.2'
port = 3306

database = 'sample_table' # In previous posts similar to "schema"

conn = pymysql.connect(Host=host,
                       port=port,
                       user=user, 
                       passwd=passw,  
                       db=database)

data.to_sql(name=database, con=conn, if_exists = 'append', index=False, flavor = 'mysql')

Je pense que cette solution pourrait être bonne même si elle n’utilise pas SQLAlchemy.

0
Rafael Valero