Je peux me connecter à ma base de données mysql locale à partir de python et créer, sélectionner et insérer des lignes individuelles.
Ma question est la suivante: puis-je demander directement à mysqldb de prendre un cadre de données complet et de l'insérer dans une table existante, ou dois-je parcourir les lignes?
Dans les deux cas, à quoi ressemblerait le script python pour une table très simple avec un ID, deux colonnes de données et un cadre de données correspondant?
Il existe maintenant une méthode to_sql
, qui est la méthode recommandée, plutôt que write_frame
:
df.to_sql(con=con, name='table_name_for_df', if_exists='replace', flavor='mysql')
Remarque: la syntaxe peut changer chez les pandas 0.14 ...
Vous pouvez configurer la connexion avec MySQLdb :
from pandas.io import sql
import MySQLdb
con = MySQLdb.connect() # may need to add some other options to connect
Définir la flavor
de write_frame
sur 'mysql'
signifie que vous pouvez écrire sur mysql:
sql.write_frame(df, con=con, name='table_name_for_df',
if_exists='replace', flavor='mysql')
L'argument if_exists
indique aux pandas comment traiter si la table existe déjà:
if_exists: {'fail', 'replace', 'append'}
, par défaut'fail'
fail
: Si la table existe, ne faites rien.replace
: Si table existe, supprimez-la, recréez-la et insérez des données.append
: Si la table existe, insérez des données. Créer si n'existe pas.
Bien que les write_frame
docs suggèrent actuellement que cela ne marche que sur sqlite, mysql semble être supporté et en fait, il y a pas mal de tests de mysql dans le codebase .
Andy Hayden a mentionné la fonction correcte ( to_sql
). Dans cette réponse, je donnerai un exemple complet, que j'ai testé avec Python 3.5 mais qui devrait également fonctionner pour Python 2.7 (et Python 3.x):
Premièrement, créons le dataframe:
# Create dataframe
import pandas as pd
import numpy as np
np.random.seed(0)
number_of_samples = 10
frame = pd.DataFrame({
'feature1': np.random.random(number_of_samples),
'feature2': np.random.random(number_of_samples),
'class': np.random.binomial(2, 0.1, size=number_of_samples),
},columns=['feature1','feature2','class'])
print(frame)
Qui donne:
feature1 feature2 class
0 0.548814 0.791725 1
1 0.715189 0.528895 0
2 0.602763 0.568045 0
3 0.544883 0.925597 0
4 0.423655 0.071036 0
5 0.645894 0.087129 0
6 0.437587 0.020218 0
7 0.891773 0.832620 1
8 0.963663 0.778157 0
9 0.383442 0.870012 0
Pour importer cette image de données dans une table MySQL:
# Import dataframe into MySQL
import sqlalchemy
database_username = 'ENTER USERNAME'
database_password = 'ENTER USERNAME PASSWORD'
database_ip = 'ENTER DATABASE IP'
database_name = 'ENTER DATABASE NAME'
database_connection = sqlalchemy.create_engine('mysql+mysqlconnector://{0}:{1}@{2}/{3}'.
format(database_username, database_password,
database_ip, database_name))
frame.to_sql(con=database_connection, name='table_name_for_df', if_exists='replace')
Une astuce est que MySQLdb ne fonctionne pas avec Python 3.x. Nous utilisons donc plutôt mysqlconnector
, qui peut être installed comme suit:
pip install mysql-connector==2.1.4 # version avoids Protobuf error
Sortie:
Notez que to_sql
crée la table ainsi que les colonnes si elles n'existent pas déjà dans la base de données.
Vous pouvez le faire en utilisant pymysql:
Par exemple, supposons que vous ayez une base de données MySQL avec l'utilisateur, le mot de passe, l'hôte et le port suivants et que vous souhaitez écrire dans la base de données 'data_2', si elle existe déjà ou non.
import pymysql
user = 'root'
passw = 'my-secret-pw-for-mysql-12ud'
Host = '172.17.0.2'
port = 3306
database = 'data_2'
Si vous avez déjà créé la base de données:
conn = pymysql.connect(Host=host,
port=port,
user=user,
passwd=passw,
db=database,
charset='utf8')
data.to_sql(name=database, con=conn, if_exists = 'replace', index=False, flavor = 'mysql')
Si vous n'avez PAS créé la base de données, également valide lorsque la base de données est déjà présente:
conn = pymysql.connect(Host=host, port=port, user=user, passwd=passw)
conn.cursor().execute("CREATE DATABASE IF NOT EXISTS {0} ".format(database))
conn = pymysql.connect(Host=host,
port=port,
user=user,
passwd=passw,
db=database,
charset='utf8')
data.to_sql(name=database, con=conn, if_exists = 'replace', index=False, flavor = 'mysql')
Fils similaires:
La méthode to_sql fonctionne pour moi.
Cependant, gardez à l'esprit qu'il semble que cela devienne obsolète en faveur de SQLAlchemy:
FutureWarning: The 'mysql' flavor with DBAPI connection is deprecated and will be removed in future versions. MySQL will be further supported with SQLAlchemy connectables. chunksize=chunksize, dtype=dtype)
from pandas.io import sql
from sqlalchemy import create_engine
engine = create_engine("mysql+pymysql://{user}:{pw}@localhost/{db}"
.format(user="root",
pw="your_password",
db="pandas"))
df.to_sql(con=engine, name='table_name', if_exists='replace')
Vous pouvez générer votre DataFrame
sous forme de fichier csv, puis utiliser mysqlimport
pour importer votre csv dans votre mysql
.
Il semblerait que sql intégré de pandas fournisse une fonction write_frame
mais ne fonctionne que dans sqlite.
J'ai trouvé quelque chose d'utile, vous pourriez essayer ceci