177 votes

Comment convertir le résultat d'une requête SQL en structure de données PANDAS ?

Toute aide sur ce problème sera grandement appréciée.

En gros, je veux exécuter une requête dans ma base de données SQL et stocker les données renvoyées dans une structure de données Pandas.

J'ai joint le code pour la requête.

Je lis la documentation sur Pandas, mais j'ai du mal à identifier le type de retour de ma requête.

J'ai essayé d'imprimer le résultat de la requête, mais cela ne donne aucune information utile.

Merci !!!!

from sqlalchemy import create_engine

engine2 = create_engine('mysql://THE DATABASE I AM ACCESSING')
connection2 = engine2.connect()
dataid = 1022
resoverall = connection2.execute("
    SELECT 
       sum(BLABLA) AS BLA,
       sum(BLABLABLA2) AS BLABLABLA2,
       sum(SOME_INT) AS SOME_INT,
       sum(SOME_INT2) AS SOME_INT2,
       100*sum(SOME_INT2)/sum(SOME_INT) AS ctr,
       sum(SOME_INT2)/sum(SOME_INT) AS cpc
    FROM daily_report_cooked
    WHERE campaign_id = '%s'",
    %dataid
)

Je veux donc comprendre quel est le format/type de données de ma variable "resoverall" et comment la placer dans la structure de données PANDAS.

181voto

Daniel Velkov Points 9244

Voici le code le plus court qui fera l'affaire :

from pandas import DataFrame
df = DataFrame(resoverall.fetchall())
df.columns = resoverall.keys()

Vous pouvez aller plus loin et analyser les types comme dans la réponse de Paul.

175voto

Bird Jaguar IV Points 2062

Edit : Mar. 2015

Comme indiqué ci-dessous, pandas utilise désormais SQLAlchemy pour lire à la fois dans ( read_sql ) et l'insérer dans ( to_sql ) une base de données. Les éléments suivants devraient fonctionner

import pandas as pd

df = pd.read_sql(sql, cnxn)

Réponse précédente : Via mikebmassey d'un question similaire

import pyodbc
import pandas.io.sql as psql

cnxn = pyodbc.connect(connection_info) 
cursor = cnxn.cursor()
sql = "SELECT * FROM TABLE"

df = psql.frame_query(sql, cnxn)
cnxn.close()

43voto

Nathan Gould Points 587

Si vous utilisez l'ORM de SQLAlchemy plutôt que le langage d'expression, il se peut que vous souhaitiez convertir un objet de type sqlalchemy.orm.query.Query dans un cadre de données Pandas.

L'approche la plus propre est d'obtenir le code SQL généré à partir de l'attribut statement de la requête, puis de l'exécuter à l'aide de la fonction pandas read_sql() méthode. Par exemple, à partir d'un objet Query appelé query :

df = pd.read_sql(query.statement, query.session.bind)

24voto

Lintang Wisesa Points 63

1. Utilisation de MySQL-connector-python

# pip install mysql-connector-python

import mysql.connector
import pandas as pd

mydb = mysql.connector.connect(
    host = 'host',
    user = 'username',
    passwd = 'pass',
    database = 'db_name'
)
query = 'select * from table_name'
df = pd.read_sql(query, con = mydb)
print(df)

2. Utilisation de SQLAlchemy

# pip install pymysql
# pip install sqlalchemy

import pandas as pd
import sqlalchemy

engine = sqlalchemy.create_engine('mysql+pymysql://username:password@localhost:3306/db_name')

query = '''
select * from table_name
'''
df = pd.read_sql_query(query, engine)
print(df)

23voto

Paul H Points 5612

Editer 2014-09-30 :

pandas dispose désormais d'une fonction read_sql fonction. Vous devez absolument l'utiliser à la place.

Réponse originale :

Je ne peux pas vous aider avec SQLAlchemy -- j'utilise toujours pyodbc, MySQLdb, ou psychopg2 selon les besoins. Mais lorsque je le fais, une fonction aussi simple que celle ci-dessous tend à répondre à mes besoins :

import decimal

import pyodbc #just corrected a typo here
import numpy as np
import pandas

cnn, cur = myConnectToDBfunction()
cmd = "SELECT * FROM myTable"
cur.execute(cmd)
dataframe = __processCursor(cur, dataframe=True)

def __processCursor(cur, dataframe=False, index=None):
    '''
    Processes a database cursor with data on it into either
    a structured numpy array or a pandas dataframe.

    input:
    cur - a pyodbc cursor that has just received data
    dataframe - bool. if false, a numpy record array is returned
                if true, return a pandas dataframe
    index - list of column(s) to use as index in a pandas dataframe
    '''
    datatypes = []
    colinfo = cur.description
    for col in colinfo:
        if col[1] == unicode:
            datatypes.append((col[0], 'U%d' % col[3]))
        elif col[1] == str:
            datatypes.append((col[0], 'S%d' % col[3]))
        elif col[1] in [float, decimal.Decimal]:
            datatypes.append((col[0], 'f4'))
        elif col[1] == datetime.datetime:
            datatypes.append((col[0], 'O4'))
        elif col[1] == int:
            datatypes.append((col[0], 'i4'))

    data = []
    for row in cur:
        data.append(tuple(row))

    array = np.array(data, dtype=datatypes)
    if dataframe:
        output = pandas.DataFrame.from_records(array)

        if index is not None:
            output = output.set_index(index)

    else:
        output = array

    return output

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X