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

사실, 내 마지막 응답 이후, 나는 사용한 적이 pyodbc과 pandas꽤 함께. 예를 들어 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

간단하게 사용 pandas과 pyodbc함께. 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.