Jak przekonwertować wynik zapytania SQL na strukturę danych?

Każda pomoc w tym problemie będzie bardzo mile widziana.

Więc w zasadzie chcę uruchomić zapytanie do mojej bazy danych SQL i zapisać zwrócone dane jako strukturę danych Pandy.

Mam załączony kod do zapytania.

Czytam dokumentację o pandach, ale mam problem z określeniem typu zwrotu mojego zapytania.

Próbowałem wydrukować wynik zapytania, ale to nie daje żadnych użytecznych informacji.

Dzięki!!!!
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)

Więc tak jakby chcę zrozumieć, jaki jest format / typ danych mojej zmiennej "resoverall" i jak umieścić go w strukturze danych pandy.

Author: jbrtrnd, 2012-08-21

15 answers

Oto najkrótszy kod, który wykona zadanie:

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

Możesz iść bardziej fantazyjnie i parsować typy jak w odpowiedzi Paula.

 72
Author: Daniel Velkov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-21 18:28:30

Edit: Mar. 2015

Jak wspomniano poniżej, pandy używają teraz SQLAlchemy zarówno do odczytu z ( read_sql), jak i wstawiania do ( to_sql ) bazy danych. Należy wykonać następujące czynności

import pandas as pd

df = pd.read_sql(sql, cnxn)

Poprzednia odpowiedź: Przez mikebmassey z podobne pytanie

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()
 91
Author: beardc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:32

Jeśli używasz ORM SQLAlchemy zamiast języka wyrażeń, możesz chcieć przekonwertować obiekt typu sqlalchemy.orm.query.Query na ramkę danych Pandy.

Najczystszym podejściem jest pobranie wygenerowanego SQL z atrybutu instrukcji zapytania, a następnie wykonanie go za pomocą metody read_sql(). Na przykład, począwszy od obiektu zapytania o nazwie query:

df = pd.read_sql(query.statement, query.session.bind)
 28
Author: Nathan Gould,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-11 03:00:55

Edycja 2014-09-30:

Pandy mają teraz funkcję read_sql. Zdecydowanie chcesz tego użyć zamiast tego.

Oryginalna odpowiedź:

Nie mogę ci pomóc z SQLAlchemy -- zawsze używam pyodbc, MySQLdb lub psychopg2 w razie potrzeby. Ale gdy to robisz, Funkcja tak prosta jak ta poniżej zwykle odpowiada moim potrzebom: {]}

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
 18
Author: Paul H,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-28 21:00:38

Podobnie jak Nathan, często chcę wrzucić wyniki zapytania SQLAlchemy lub Sqlsoup do ramki danych Pandy. Moje własne rozwiązanie to:

query = session.query(tbl.Field1, tbl.Field2)
DataFrame(query.all(), columns=[column['name'] for column in query.column_descriptions])
 4
Author: Janak Mayer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-02 18:53:25

Po prostu użyj pandas i pyodbc razem. Będziesz musiał zmodyfikować Łańcuch Połączenia (connstr) zgodnie ze specyfikacją bazy danych.

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

Używałem pyodbc z kilkoma firmowymi bazami danych (np. SQL Server, MySQL, MariaDB, IBM).

 4
Author: openwonk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-16 15:59:21

resoverall jest obiektem SQLAlchemy ResultProxy. Więcej na ten temat można przeczytać w dokumentach sqlalchemy , Ta ostatnia wyjaśnia podstawowe zastosowanie pracy z silnikami i połączeniami. Ważne jest to, że {[0] } jest dict jak.

Pandy lubią dict like objects, aby tworzyć swoje struktury danych, zobacz Online docs

Powodzenia z sqlalchemy i pand.
 3
Author: Wouter Overmeire,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-21 12:36:18

To pytanie jest stare, ale chciałem dodać moje dwa grosze. Przeczytałem pytanie jako " chcę uruchomić zapytanie do mojej [mojej]bazy danych SQL i zapisać zwrócone dane jako strukturę danych [DataFrame]."

Z kodu wynika, że masz na myśli bazę danych mysql i zakładamy, że masz na myśli pandy 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)

Na przykład,

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

Spowoduje zaimportowanie wszystkich wierszy testTable do ramki danych.

 3
Author: joelotz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-31 18:55:22

MySQL Connector

Dla tych, którzy pracują z mysql connector można użyć tego kodu jako początek. (Dzięki @ Daniel Velkov)

Używane refs:


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())
 2
Author: Thomas Devoogdt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-06 09:06:28

Oto kod, którego używam. Mam nadzieję, że to pomoże.

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)
 2
Author: Murali Bala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-06 16:01:00

To krótka i wyraźna odpowiedź na twój problem:

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)
 2
Author: DeshDeep Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-12 14:55:47

Długi czas od ostatniego posta, ale może to komuś pomoże...

Skrócony sposób niż Paweł H:

my_dic = session.query(query.all())
my_df = pandas.DataFrame.from_dict(my_dic)
 0
Author: Antonio Fernandez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-23 09:21:05

Best way I do this

db.execute(query) where db=db_class() #database class
    mydata=[x for x in db.fetchall()]
    df=pd.DataFrame(data=mydata)
 0
Author: Berto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-09 08:55:58

Tutaj jest mój. Na wszelki wypadek jeśli używasz "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
 0
Author: kennyut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-05 15:57:02

Jeśli typem wyniku jest ResultSet , powinieneś najpierw przekonwertować go na słownik. Następnie kolumny DataFrame zostaną automatycznie pobrane.

To działa w mojej sprawie:

df = pd.DataFrame([dict(r) for r in resoverall])
 0
Author: tanza9,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-14 06:43:07