SQL 쿼리 결과를 PANDAS 데이터 구조로 변환하는 방법은 무엇입니까?


116

이 문제에 대한 도움을 주시면 대단히 감사하겠습니다.

그래서 기본적으로 SQL 데이터베이스에 대한 쿼리를 실행하고 반환 된 데이터를 Pandas 데이터 구조로 저장하고 싶습니다.

쿼리 코드를 첨부했습니다.

Pandas에 대한 문서를 읽고 있지만 쿼리의 반환 유형을 식별하는 데 문제가 있습니다.

쿼리 결과를 인쇄하려고했지만 유용한 정보를 제공하지 않습니다.

감사!!!!

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)

그래서 나는 내 변수 "resoverall"의 형식 / 데이터 유형이 무엇인지, 그리고 그것을 PANDAS 데이터 구조에 넣는 방법을 이해하고 싶습니다.


기본적으로 "resoverall"변수의 구조 / 유형은 무엇이며이를 Pandas 데이터 구조로 변환하는 방법입니다.
user1613017 2012-08-21

팬더는 꽤 흥미로워 보이지만 전에는 들어 본 적이 없지만이 질문은 거의 이해가되지 않습니다. "유용한 정보를 제공하지 않는다"는 의미를 명확히 할 수 있습니까?
tadman

1
내가 실행 한 쿼리가 반환을 제공하기 때문에이 반환을 어떻게 조작하고 팬더 데이터 구조로 만들어야할지 궁금합니다. 저는 파이썬을 처음 접했기 때문에 지식이 많지 않습니다. PHP에서하는 일이 sql_fetch_array를 수행하고 "사용 가능한"데이터가있는 것처럼 말입니다. =)
user1613017

답변:


120

다음은 작업을 수행 할 가장 짧은 코드입니다.

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

Paul의 대답과 같이 더 멋지게 가고 유형을 구문 분석 할 수 있습니다.


1
이것은 Oracle 데이터베이스에서 감염된 1.000.000 레코드에 대해 저에게 효과적이었습니다.
Erdem KAYA

8
df = DataFrame(cursor.fetchall())을 반환 ValueError: DataFrame constructor not properly called!하면 튜플의 튜플이 DataFrame 생성자에 허용되지 않는 것으로 보입니다. .keys()사전 또는 튜플 모드 에도 커서 가 없습니다 .
Mobigital

3
keys 메소드는 sqlalchemy를 사용하여 얻은 결과에만 작동합니다. Pyodbc는 열에 대한 설명 속성을 사용합니다.
Filip

Postgres 데이터베이스에서 작동 할 수 있습니까? keys()함수 를 사용하여 결과 데이터 프레임의 열 이름을 얻으려고 하지만 작동하지 않습니다.
Bowen Liu

1
@BowenLiu 예, psycopg2와 함께 사용할 수 있습니다df.columns=[ x.name for x in recoverall.description ]
Gnudiff

136

편집 : 2015 년 3 월

아래에 언급 된 바와 같이, 팬더 현재 사용 SQLAlchemy의가 (모두로부터 읽어 read_sql ) 및 (삽입 to_sql ) 데이터베이스. 다음이 작동합니다.

import pandas as pd

df = pd.read_sql(sql, cnxn)

이전 답변 : 비슷한 질문의 mikebmassey를 통해

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

열 인덱스를 얻기 위해 .keys ()를 수동으로 사용할 필요가 없기 때문에 이것이 최선의 방법 인 것 같습니다. 아마도 Daniel의 대답은이 방법이 존재하기 전에 작성되었습니다. pandas.io.sql.read_frame ()을 사용할 수도 있습니다
RobinL

1
@openwonk pd.read_sql()위의 코드 스 니펫에서 구현할 위치는 어디 입니까?
3kstc

사실, 내 마지막 응답 이후, 나는 사용한 적이 pyodbcpandas꽤 함께. 예를 들어 FYI로 새로운 답변을 추가합니다.
openwonk

33

표현식 언어가 아닌 SQLAlchemy의 ORM을 사용하는 경우 유형의 객체를 sqlalchemy.orm.query.QueryPandas 데이터 프레임 으로 변환하고 싶을 수 있습니다 .

가장 깔끔한 접근 방식은 쿼리의 문 속성에서 생성 된 SQL을 가져온 다음 pandas의 read_sql()메서드 로 실행하는 것입니다 . 예를 들어 다음과 같은 Query 객체로 시작합니다 query.

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

5
보다 효율적인 접근 방법은 SQLAlchemy의에서 문을 얻고 팬더와 쿼리 자체를 할 수 있도록하는 것입니다 pandas.read_sql_query통과, query.statement그것. 이 대답을 참조하십시오 stackoverflow.com/a/29528804/1273938
LeoRochael

@LeoRochael 감사합니다! 내 대답을 수정했습니다. 확실히 깨끗합니다!
Nathan Gould

23

2014-09-30 수정 :

팬더에는 이제 read_sql기능이 있습니다. 대신 사용하고 싶을 것입니다.

원래 답변 :

SQLAlchemy에 대해 도움을 드릴 수 없습니다. 필요에 따라 항상 pyodbc, MySQLdb 또는 psychopg2를 사용합니다. 그러나 그렇게 할 때 아래의 것과 같은 간단한 기능이 내 요구에 맞는 경향이 있습니다.

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

십진수를 맨 위로 가져와야한다고 생각합니까?
joefromct 2015 년

@joefromct 아마도이 답변은 너무 구식이어서 모든 것을 치고 판다 방법을 보여야합니다.
Paul H

일부 관련이있을 수 있습니다 ... 제가 이것을 연구 한 이유는 여기에 read_sql ()을 사용하는 다른 문제 때문이었습니다. stackoverflow.com/questions/32847246/…
joefromct

모든 데이터베이스를 지원하지 않는 SQLAlchemy를 사용할 수없는 사람들과 관련이 있습니다.
lamecicle

@lamecicle은 다소 동의하지 않습니다. IIRC, read_sql예를 들어 pyodbc, psychopg2 등을 통해 비 SQLAlchemy 연결을 계속 허용 할 수 있습니다.
Paul H

16

MySQL 커넥터

mysql 커넥터와 함께 작동하는 경우이 코드를 시작으로 사용할 수 있습니다. (@Daniel Velkov에게 감사드립니다)

사용 된 심판 :


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

9

내가 사용하는 코드는 다음과 같습니다. 도움이 되었기를 바랍니다.

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

이것은 귀하의 문제에 대한 짧고 명확한 대답입니다.

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)

8

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

간단하고 훌륭한 답변!
Lucas Aimaretto

5

Nathan처럼 저는 종종 sqlalchemy 또는 sqlsoup 쿼리의 결과를 Pandas 데이터 프레임에 덤프하고 싶습니다. 이에 대한 내 자신의 해결책은 다음과 같습니다.

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

1
쿼리 개체가있는 경우. 그것은 SQLAlchemy의에서 문을 얻고 팬더와 쿼리 자체를 할 수 있도록하는 것이 더 효율적 pandas.read_sql_query전달 query.statement그것. 이 대답을 참조하십시오 stackoverflow.com/a/29528804/1273938
LeoRochael

4

resoverallsqlalchemy ResultProxy 객체입니다. 자세한 내용은 sqlalchemy 문서 에서 읽을 수 있으며 후자는 엔진 및 연결 작업의 기본 사용법을 설명합니다. 여기서 중요한 resoverall것은 dict와 같은 것입니다.

Pandas는 데이터 구조를 만들기 위해 객체와 같은 dict를 좋아합니다. 온라인 문서를 참조하세요.

sqlalchemy와 pandas에 행운을 빕니다.


4

간단하게 사용 pandaspyodbc함께. connstr데이터베이스 사양에 따라 연결 문자열 ( ) 을 수정해야합니다 .

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

pyodbc여러 엔터프라이즈 데이터베이스 (예 : SQL Server, MySQL, MariaDB, IBM)를 사용해 왔습니다 .


Pyodbc를 사용하여이 데이터 프레임을 다시 MSSQL에 다시 쓰는 방법은 무엇입니까? Otherthan 사용 SQLAlchemy의
램지

개체에 to_sql메서드를 사용하십시오 DataFrame. 이 메서드는 기본적으로 SQLite로 설정되어 있으므로 MSSQL 데이터베이스를 가리키는 개체를 명시 적으로 전달해야합니다. 문서를 참조하십시오 .
openwonk

나는 아래의 것을 시도했고 13 열이있는 약 200K 행이 있습니다. 15 분 후에도 완료되지 않습니다. 어떤 아이디어? df.to_sql ( 'tablename', engine, schema = 'schemaname', if_exists = 'append', index = False)
Ramsey

느린 것 같습니다. 전체 코드가 작동하는 것을 확인해야합니다. 죄송합니다. I 소원은 pandas더 많은 빛 ETL 작업에 최적화 된, 그러나 슬프 도다 ... 한
openwonk

3

이 질문은 오래되었지만 2 센트를 추가하고 싶었습니다. "내 [my] SQL 데이터베이스에 대한 쿼리를 실행하고 반환 된 데이터를 Pandas 데이터 구조 [DataFrame]로 저장하고 싶습니다."라는 질문을 읽었습니다.

코드에서 보면 mysql 데이터베이스를 의미하고 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)

예를 들면

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

이것은 testTable의 모든 행을 DataFrame으로 가져옵니다.


1

여기 내 꺼야. "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

pandas.io.sql.write_frame은 DEPRECATED입니다. https://pandas.pydata.org/pandas-docs/version/0.15.2/generated/pandas.io.sql.write_frame.html

pandas.DataFrame.to_sql https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_sql.html 을 사용하도록 변경해야합니다.

또 다른 해결책이 있습니다. PYODBC to Pandas-DataFrame이 작동하지 않음-전달 된 값의 모양은 (x, y), 인덱스는 (w, z)를 의미합니다.

Pandas 0.12 (내 생각에)부터 다음을 수행 할 수 있습니다.

import pandas
import pyodbc

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

data = pandas.read_sql(sql, cnn)

0.12 이전에는 다음을 수행 할 수 있습니다.

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

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

data = read_frame(sql, cnn)

이것이 가장 쉬운 방법입니다
Wilmer E. Henao

0

지난 게시물에서 오래되었지만 누군가에게 도움이 될 수도 있습니다 ...

Paul H보다 짧은 길 :

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

0

내가 이것을하는 가장 좋은 방법

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

0

결과 유형이 ResultSet 인 경우 먼저 사전으로 변환해야합니다. 그러면 DataFrame 열 이 자동으로 수집됩니다.

이것은 내 경우에서 작동합니다.

df = pd.DataFrame([dict(r) for r in resoverall])
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.