web-dev-qa-db-fra.com

Comment insérer des données de pandas via mysqldb dans la base de données?

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?

26
Stefan

Mettre à jour:

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 .

60
Andy Hayden

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:

 enter image description here

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.

7
Franck Dernoncourt

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:

  1. Ecrire dans la base de données MySQL avec des pandas utilisant SQLAlchemy, to_sql
  2. Ecrire un fichier de données de pandas dans MySQL
2
Rafael Valero

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)
1
Alex_L

Python 2 + 3

Pré-requis

  • Pandas
  • Serveur MySQL
  • sqlalchemy
  • pymysql : client mysql pur python

Code

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')
1
Martin Thoma

Vous pouvez générer votre DataFrame sous forme de fichier csv, puis utiliser mysqlimport pour importer votre csv dans votre mysql.

MODIFIER

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

1
waitingkuo