web-dev-qa-db-fra.com

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

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

Je souhaite donc lancer une requête sur ma base de données SQL et stocker les données renvoyées sous forme de structure de données Pandas.

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

Je lis la documentation sur les 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 en quelque sorte comprendre quel est le format/type de données de ma variable "resoverall" et comment le mettre avec la structure de données PANDAS.

91
user1613017

Voici le code le plus court qui fera le travail:

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

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

96
Daniel Velkov

Edit: mars 2015

Comme indiqué ci-dessous, pandas utilise maintenant SQLAlchemy pour lire à partir de ( read_sql ) et insérer dans ( to_sql ) une base de données . Ce qui suit devrait fonctionner

import pandas as pd

df = pd.read_sql(sql, cnxn)

Réponse précédente: via mikebmassey à partir 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()
115
beardc

Si vous utilisez l'ORM de SQLAlchemy plutôt que le langage d'expression, vous voudrez peut-être convertir un objet de type sqlalchemy.orm.query.Query en un cadre de données Pandas.

L'approche la plus propre consiste à extraire le code SQL généré à partir de l'attribut statement de la requête, puis à l'exécuter avec la méthode read_sql() de pandas. Par exemple, en commençant par un objet de requête appelé query:

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

Edit 2014-09-30:

les pandas ont maintenant une fonction read_sql. Vous voulez certainement utiliser cela à la place.

Réponse originale:

Je ne peux pas vous aider avec SQLAlchemy - J'utilise toujours pyodbc, MySQLdb ou psychopg2 selon les besoins. Mais ce faisant, une fonction aussi simple que celle ci-dessous répond à mes besoins:

import decimal

import pydobc
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
23
Paul H

Connecteur MySQL

Pour ceux qui fonctionnent avec le connecteur mysql, vous pouvez utiliser ce code comme point de départ. (Merci à @Daniel Velkov)

Refs utilisés:


import pandas as pd
import mysql.connector

# Setup MySQL connection
db = mysql.connector.connect(
    Host="<IP>",              # your Host, usually localhost
    user="<USER>",            # your username
    password="<PASS>",        # your password
    database="<DATABASE>"     # name of the data base
)   

# You must create a Cursor object. It will let you execute all the queries you need
cur = db.cursor()

# Use all the SQL you like
cur.execute("SELECT * FROM <TABLE>")

# Put it all to a data frame
sql_data = pd.DataFrame(cur.fetchall())
sql_data.columns = cur.column_names

# Close the session
db.close()

# Show the data
print(sql_data.head())
12
Thomas Devoogdt

Voici le code que j'utilise. J'espère que cela t'aides.

import pandas as pd
from sqlalchemy import create_engine

def getData():
  # Parameters
  ServerName = "my_server"
  Database = "my_db"
  UserPwd = "user:pwd"
  Driver = "driver=SQL Server Native Client 11.0"

  # Create the connection
  engine = create_engine('mssql+pyodbc://' + UserPwd + '@' + ServerName + '/' + Database + "?" + Driver)

  sql = "select * from mytable"
  df = pd.read_sql(sql, engine)
  return df

df2 = getData()
print(df2)
9
Murali Bala

Voici une réponse brève et précise à votre problème:

from __future__ import print_function
import MySQLdb
import numpy as np
import pandas as pd
import xlrd

# Connecting to MySQL Database
connection = MySQLdb.connect(
             Host="hostname",
             port=0000,
             user="userID",
             passwd="password",
             db="table_documents",
             charset='utf8'
           )
print(connection)
#getting data from database into a dataframe
sql_for_df = 'select * from tabledata'
df_from_database = pd.read_sql(sql_for_df , connection)
5
DeshDeep Singh

resoverall est un objet sqlalchemy ResultProxy. Vous pouvez en savoir plus à ce sujet dans document sqlalchemy , ce dernier explique l'utilisation de base du travail avec les moteurs et les connexions. Il est important de noter que resoverall est dicté.

Les pandas aiment dict comme des objets pour créer leurs structures de données, voir la documentation en ligne

Bonne chance avec sqlalchemy et les pandas.

4
Wouter Overmeire

Utilisez simplement pandas et pyodbc ensemble. Vous devrez modifier votre chaîne de connexion (connstr) en fonction des spécifications de votre base de données.

import pyodbc
import pandas as pd

# MSSQL Connection String Example
connstr = "Server=myServerAddress;Database=myDB;User Id=myUsername;Password=myPass;"

# Query Database and Create DataFrame Using Results
df = pd.read_sql("select * from myTable", pyodbc.connect(connstr))

J'ai utilisé pyodbc avec plusieurs bases de données d'entreprise (par exemple, SQL Server, MySQL, MariaDB, IBM).

4
openwonk

Comme Nathan, je souhaite souvent transférer les résultats d'une requête sqlalchemy ou sqlsoup dans un cadre de données Pandas. Ma propre solution est la suivante:

query = session.query(tbl.Field1, tbl.Field2)
DataFrame(query.all(), columns=[column['name'] for column in query.column_descriptions])
4
Janak Mayer

Cette question est ancienne, mais je voulais ajouter mes deux centimes. J'ai lu la question comme suit: "Je souhaite lancer une requête sur ma [ma] base de données SQL et stocker les données renvoyées sous la forme de la structure de données Pandas [DataFrame]".

D'après le code, on dirait que vous voulez dire base de données mysql et supposez que vous voulez dire pandas DataFrame.

import MySQLdb as mdb
import pandas.io.sql as sql
from pandas import *

conn = mdb.connect('<server>','<user>','<pass>','<db>');
df = sql.read_frame('<query>', conn)

Par exemple,

conn = mdb.connect('localhost','myname','mypass','testdb');
df = sql.read_frame('select * from testTable', conn)

Cela importera toutes les lignes de testTable dans un DataFrame.

3
joelotz

Voici le mien. Juste au cas où vous utiliseriez "pymysql":

import pymysql
from pandas import DataFrame

Host   = 'localhost'
port   = 3306
user   = 'yourUserName'
passwd = 'yourPassword'
db     = 'yourDatabase'

cnx    = pymysql.connect(Host=host, port=port, user=user, passwd=passwd, db=db)
cur    = cnx.cursor()

query  = """ SELECT * FROM yourTable LIMIT 10"""
cur.execute(query)

field_names = [i[0] for i in cur.description]
get_data = [xx for xx in cur]

cur.close()
cnx.close()

df = DataFrame(get_data)
df.columns = field_names
1
kennyut

pandas.io.sql.write_frame est DEPRECATED. https://pandas.pydata.org/pandas-docs/version/0.15.2/generated/pandas.io.sql.write_frame.html

Devrait changer pour utiliser pandas.DataFrame.to_sql https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_sql.html

Il y a une autre solution. PYODBC à Pandas - DataFrame ne fonctionne pas - La forme des valeurs transmises est (x, y), les indices impliquent (w, z)

À partir de Pandas 0.12 (je crois), vous pouvez faire:

import pandas
import pyodbc

sql = 'select * from table'
cnn = pyodbc.connect(...)

data = pandas.read_sql(sql, cnn)

Avant 0.12, vous pourriez faire:

import pandas
from pandas.io.sql import read_frame
import pyodbc

sql = 'select * from table'
cnn = pyodbc.connect(...)

data = read_frame(sql, cnn)
0
江明哲

Long time from last post mais peut-être que ça aide quelqu'un ...

Chemin court que Paul H:

my_dic = session.query(query.all())
my_df = pandas.DataFrame.from_dict(my_dic)
0
Antonio Fernandez

1. Utiliser 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)
0
Lintang Wisesa

Si le type de résultat est ResultSet, vous devez d'abord le convertir en dictionnaire. Ensuite, les colonnes DataFrame seront automatiquement collectées.

Cela fonctionne sur mon cas:

df = pd.DataFrame([dict(r) for r in resoverall])
0
tanza9

meilleur moyen de le faire

db.execute(query) where db=db_class() #database class
    mydata=[x for x in db.fetchall()]
    df=pd.DataFrame(data=mydata)
0
Berto