python-pandas và cơ sở dữ liệu như mysql


97

Tài liệu cho Gấu trúc có nhiều ví dụ về các phương pháp hay nhất để làm việc với dữ liệu được lưu trữ ở các định dạng khác nhau.

Tuy nhiên, tôi không thể tìm thấy bất kỳ ví dụ tốt nào để làm việc với cơ sở dữ liệu như MySQL chẳng hạn.

Bất cứ ai có thể chỉ cho tôi liên kết hoặc cung cấp một số đoạn mã về cách chuyển đổi kết quả truy vấn bằng cách sử dụng mysql-python thành khung dữ liệu trong Pandas một cách hiệu quả không?




Cũng hãy xem Blaze .
osa

Nếu bạn sẵn sàng chi tiền, tôi tin rằng cuốn sách của Wes McKinney ("Python để phân tích dữ liệu") có một số ví dụ hữu ích.
MTrenfield

Câu trả lời:


102

Như Wes đã nói, read_sql của io / sql sẽ làm được điều đó, khi bạn đã có kết nối cơ sở dữ liệu bằng thư viện tương thích DBI. Chúng ta có thể xem xét hai ví dụ ngắn sử dụng thư viện MySQLdbcx_Oracleđể kết nối với Oracle và MySQL và truy vấn từ điển dữ liệu của chúng. Đây là ví dụ cho 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()

Và đây là ví dụ tương đương cho 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()

57

Đối với những độc giả gần đây của câu hỏi này: gấu trúc có cảnh báo sau trong tài liệu của chúng cho phiên bản 14.0 :

Cảnh báo: Một số hàm hiện có hoặc bí danh hàm không được dùng nữa và sẽ bị xóa trong các phiên bản sau. Điều này bao gồm: tquery, uquery, read_frame, frame_query, write_frame.

Và:

Cảnh báo: Hỗ trợ cho hương vị 'mysql' khi sử dụng các đối tượng kết nối DBAPI đã không được chấp nhận. MySQL sẽ được hỗ trợ thêm với các công cụ SQLAlchemy (GH6900).

Điều này làm cho nhiều câu trả lời ở đây đã lỗi thời. Bạn nên sử dụng 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')

tải một bảng có 133 hàng và 7 cột mất khoảng 30 giây .. bạn có thể cung cấp một số thông tin chi tiết về lý do tại sao lại như vậy không?
idoda

@idoda [nói chung đây không phải là chủ đề của câu hỏi và tốt hơn hết bạn nên đặt một câu hỏi mới để bạn có thêm ý kiến]. Bạn có chắc đây không phải là vấn đề của sự chậm trễ yêu cầu? Việc gửi truy vấn và truy xuất kết quả có nhanh hơn đáng kể không?
Korem

@Korem Tôi đã nghĩ đến việc mở một cái mới, nhưng trước tiên tôi muốn đảm bảo rằng nó không phải là một cái tầm thường. Khi tôi sử dụng máy khách mySql (Sequel pro) và truy vấn cơ sở dữ liệu, việc sử dụng lại sẽ nhanh hơn nhiều. Khi bạn nói "chỉ cần gửi và sau đó truy xuất", đó có phải là ý bạn? (sử dụng một khách hàng)
idoda

@idoda Ý tôi là so sánh thời gian cần thiết để thực hiện engine.execute("select * FROM mytable")với thời gian cần thiết để thực hiệnpd.read_sql_query('SELECT * FROM mytable', engine)
Korem

Người ta có thể chuyển một truy vấn sqlalchemy (session.query như trong câu trả lời của tôi bên dưới) trực tiếp đến một phương thức pandas không? Đó sẽ là một kẻ gian!
dmvianna

23

Đối với bản ghi, đây là một ví dụ sử dụng cơ sở dữ liệu 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

1
Bạn có thể chỉ định cột để sử dụng làm chỉ mục bằng cách chỉ định index_col='timestamp'trong frame_query.
Ốc cơ

19

Tôi thích tạo các truy vấn bằng SQLAlchemy , và sau đó tạo một DataFrame từ nó. SQLAlchemy làm cho việc kết hợp các điều kiện SQL trở nên dễ dàng hơn nếu bạn có ý định trộn và kết hợp nhiều thứ.

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)

Ngoài ra bạn phải xác định người lái xe nếu nó không giống như một mặc định của SQLAlchemy :dialect+driver://user:pwd@host:port/db
Nuno André

11

Ví dụ về 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)

7
frame_queryhiện không được dùng nữa. Bây giờ sử dụng pd.read_sql(query, db)thay thế.
Robert Smith

8

Cú pháp tương tự cũng hoạt động đối với máy chủ Ms SQL bằng cách sử dụng podbc.

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

5

Và đây là cách bạn kết nối với PostgreSQL bằng trình điều khiển psycopg2 (cài đặt bằng "apt-get install python-psycopg2" nếu bạn đang sử dụng hệ điều hành phái sinh 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)


4

pandas.io.sql.frame_querykhông được dùng nữa. Sử dụng pandas.read_sqlthay thế.


1

nhập mô-đun

import pandas as pd
import oursql

kết nối

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

Điều đó hoạt động tốt và sử dụng frame_works pandas.io.sql (với cảnh báo không dùng nữa). Cơ sở dữ liệu được sử dụng là cơ sở dữ liệu mẫu từ hướng dẫn mysql.


0

Điều này sẽ hoạt động tốt.

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

0

Điều này đã giúp tôi kết nối với AWS MYSQL (RDS) từ hàm lambda dựa trên python 3.x và tải vào DataFrame gấu trúc

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
    #}

0

Đối với người dùng 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

1
Bạn có thể chỉ ra sự khác biệt trong câu trả lời của @Will và tại sao nên chọn giải pháp của bạn không?
Sebastian
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.