python-pandas dan database seperti mysql

97

Dokumentasi untuk Pandas memiliki banyak contoh praktik terbaik untuk bekerja dengan data yang disimpan dalam berbagai format.

Namun, saya tidak dapat menemukan contoh bagus untuk bekerja dengan database seperti MySQL misalnya.

Adakah yang bisa mengarahkan saya ke tautan atau memberikan beberapa cuplikan kode tentang cara mengonversi hasil kueri menggunakan mysql-python ke bingkai data di Pandas secara efisien?

pengguna1320615
sumber
Lihat juga: stackoverflow.com/questions/15231646/…
Siput mekanik
Lihat juga Blaze .
osa
Jika Anda bersedia mengeluarkan uang, saya yakin buku Wes McKinney ("Python untuk Analisis Data") memiliki beberapa contoh yang berguna.
MTrenfield

Jawaban:

102

Seperti yang dikatakan Wes, read_sql io / sql akan melakukannya, setelah Anda mendapatkan koneksi database menggunakan pustaka yang kompatibel dengan DBI. Kita dapat melihat dua contoh singkat menggunakan MySQLdbdan cx_Oracleperpustakaan untuk terhubung ke Oracle dan MySQL dan menanyakan kamus datanya. Ini contohnya untuk cx_Oracle:

import pandas as pd
import cx_Oracle

ora_conn = cx_Oracle.connect('your_connection_string')
df_ora = pd.read_sql('select * from user_objects', con=ora_conn)    
print 'loaded dataframe from Oracle. # Records: ', len(df_ora)
ora_conn.close()

Dan berikut adalah contoh yang setara untuk MySQLdb:

import MySQLdb
mysql_cn= MySQLdb.connect(host='myhost', 
                port=3306,user='myusername', passwd='mypassword', 
                db='information_schema')
df_mysql = pd.read_sql('select * from VIEWS;', con=mysql_cn)    
print 'loaded dataframe from MySQL. records:', len(df_mysql)
mysql_cn.close()
Keith C Campbell
sumber
57

Untuk pembaca baru dari pertanyaan ini: panda memiliki peringatan berikut di dokumen mereka untuk versi 14.0 :

Peringatan: Beberapa fungsi atau alias fungsi sudah tidak digunakan lagi dan akan dihapus di versi mendatang. Ini termasuk: tquery, uquery, read_frame, frame_query, write_frame.

Dan:

Peringatan: Dukungan untuk ragam 'mysql' saat menggunakan objek koneksi DBAPI sudah tidak digunakan lagi. MySQL akan lebih didukung dengan mesin SQLAlchemy (GH6900).

Hal ini membuat banyak jawaban di sini menjadi kuno. Anda harus menggunakan sqlalchemy:

from sqlalchemy import create_engine
import pandas as pd
engine = create_engine('dialect://user:pass@host:port/schema', echo=False)
f = pd.read_sql_query('SELECT * FROM mytable', engine, index_col = 'ID')
Korem
sumber
memuat tabel dengan 133 baris dan 7 kolom membutuhkan waktu sekitar 30 detik .. dapatkah Anda memberikan beberapa wawasan tentang mengapa demikian?
idoda
@idoda [secara umum ini bukan topik pertanyaan dan lebih baik mengajukan pertanyaan baru agar Anda mendapatkan lebih banyak opini]. Apakah Anda yakin ini bukan masalah penundaan permintaan? Apakah hanya mengirim kueri dan mengambil hasilnya secara signifikan lebih cepat?
Korem
@Korem Saya memang berpikir untuk membuka yang baru, tapi saya ingin memastikan itu bukan hal yang sepele dulu. Ketika saya menggunakan klien mySql (Sequel pro) dan query database, reuslts muncul lebih cepat. Ketika Anda mengatakan "hanya mengirim dan kemudian mengambil", apakah itu yang Anda maksud? (menggunakan klien)
idoda
@idoda Maksud saya membandingkan waktu yang diperlukan untuk mengeksekusi engine.execute("select * FROM mytable")dengan waktu yang diperlukan untuk mengeksekusipd.read_sql_query('SELECT * FROM mytable', engine)
Korem
Bisakah seseorang melewatkan kueri sqlalchemy (session.query seperti dalam jawaban saya di bawah) langsung ke metode pandas? Itu akan menjadi ripper!
dmvianna
23

Sebagai catatan, berikut adalah contoh penggunaan database sqlite:

import pandas as pd
import sqlite3

with sqlite3.connect("whatever.sqlite") as con:
    sql = "SELECT * FROM table_name"
    df = pd.read_sql_query(sql, con)
    print df.shape
mbatchkarov.dll
sumber
1
Anda dapat menentukan kolom yang akan digunakan sebagai indeks dengan menentukan index_col='timestamp'dalam frame_query.
Siput mekanik
19

Saya lebih suka membuat kueri dengan SQLAlchemy , dan kemudian membuat DataFrame darinya. SQLAlchemy membuatnya lebih mudah untuk menggabungkan kondisi SQL secara Python jika Anda berniat untuk mencampur dan mencocokkan banyak hal berulang kali.

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Table
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from pandas import DataFrame
import datetime

# We are connecting to an existing service
engine = create_engine('dialect://user:pwd@host:port/db', echo=False)
Session = sessionmaker(bind=engine)
session = Session()
Base = declarative_base()

# And we want to query an existing table
tablename = Table('tablename', 
    Base.metadata, 
    autoload=True, 
    autoload_with=engine, 
    schema='ownername')

# These are the "Where" parameters, but I could as easily 
# create joins and limit results
us = tablename.c.country_code.in_(['US','MX'])
dc = tablename.c.locn_name.like('%DC%')
dt = tablename.c.arr_date >= datetime.date.today() # Give me convenience or...

q = session.query(tablename).\
            filter(us & dc & dt) # That's where the magic happens!!!

def querydb(query):
    """
    Function to execute query and return DataFrame.
    """
    df = DataFrame(query.all());
    df.columns = [x['name'] for x in query.column_descriptions]
    return df

querydb(q)
dmvianna
sumber
Anda juga harus menentukan driver jika tidak sama dengan default SQLAlchemy :dialect+driver://user:pwd@host:port/db
Nuno André
11

Contoh MySQL:

import MySQLdb as db
from pandas import DataFrame
from pandas.io.sql import frame_query

database = db.connect('localhost','username','password','database')
data     = frame_query("SELECT * FROM data", database)
aerkenemesis
sumber
7
frame_querysekarang tidak digunakan lagi. Sekarang gunakan pd.read_sql(query, db)saja.
Robert Smith
8

Sintaks yang sama berfungsi untuk server Ms SQL yang menggunakan podbc juga.

import pyodbc
import pandas.io.sql as psql

cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=servername;DATABASE=mydb;UID=username;PWD=password') 
cursor = cnxn.cursor()
sql = ("""select * from mytable""")

df = psql.frame_query(sql, cnxn)
cnxn.close()
hedgcutter
sumber
5

Dan ini adalah cara Anda terhubung ke PostgreSQL menggunakan driver psycopg2 (instal dengan "apt-get install python-psycopg2" jika Anda menggunakan OS turunan Debian Linux).

import pandas.io.sql as psql
import psycopg2

conn = psycopg2.connect("dbname='datawarehouse' user='user1' host='localhost' password='uberdba'")

q = """select month_idx, sum(payment) from bi_some_table"""

df3 = psql.frame_query(q, conn)
Akan
sumber
4

Untuk Sybase, pekerjaan berikut (dengan http://python-sybase.sourceforge.net )

import pandas.io.sql as psql
import Sybase

df = psql.frame_query("<Query>", con=Sybase.connect("<dsn>", "<user>", "<pwd>"))
pengguna1827356
sumber
4

pandas.io.sql.frame_querysudah ditinggalkan. Gunakan pandas.read_sqlsebagai gantinya.

ajkl
sumber
1

impor modul

import pandas as pd
import oursql

Menghubung

conn=oursql.connect(host="localhost",user="me",passwd="mypassword",db="classicmodels")
sql="Select customerName, city,country from customers order by customerName,country,city"
df_mysql = pd.read_sql(sql,conn)
print df_mysql

Itu berfungsi dengan baik dan menggunakan pandas.io.sql frame_works (dengan peringatan penghentian). Database yang digunakan adalah database sampel dari tutorial mysql.

pengguna5925400
sumber
0

Ini seharusnya bekerja dengan baik.

import MySQLdb as mdb
import pandas as pd
con = mdb.connect(‘127.0.0.1’, root’, password’, database_name’);
with con:
 cur = con.cursor()
 cur.execute(“select random_number_one, random_number_two, random_number_three from randomness.a_random_table”)
 rows = cur.fetchall()
 df = pd.DataFrame( [[ij for ij in i] for i in rows] )
 df.rename(columns={0: Random Number One’, 1: Random Number Two’, 2: Random Number Three’}, inplace=True);
 print(df.head(20))
MontyPython
sumber
0

Ini membantu saya untuk menghubungkan ke AWS MYSQL (RDS) dari fungsi lambda berbasis python 3.x. dan memuat ke DataFrame pandas

import json
import boto3
import pymysql
import pandas as pd
user = 'username'
password = 'XXXXXXX'
client = boto3.client('rds')
def lambda_handler(event, context):
    conn = pymysql.connect(host='xxx.xxxxus-west-2.rds.amazonaws.com', port=3306, user=user, passwd=password, db='database name', connect_timeout=5)
    df= pd.read_sql('select * from TableName limit 10',con=conn)
    print(df)
    # TODO implement
    #return {
    #    'statusCode': 200,
    #    'df': df
    #}
Dheeraj
sumber
0

Untuk pengguna Postgres

import psycopg2
import pandas as pd

conn = psycopg2.connect("database='datawarehouse' user='user1' host='localhost' password='uberdba'")

customers = 'select * from customers'

customers_df = pd.read_sql(customers,conn)

customers_df
EvaMwangi
sumber
1
Bisakah Anda menunjukkan perbedaan jawaban @Will dan mengapa solusi Anda harus dipilih?
Sebastian