Python-панды и базы данных, такие как MySQL
Документация для Pandas содержит множество примеров лучших практик для работы с данными, хранящимися в различных форматах.
Однако я не могу найти хороших примеров для работы с базами данных, например, MySQL.
Может кто-нибудь указать мне ссылки или дать некоторые фрагменты кода о том, как эффективно преобразовать результаты запроса, используя mysql-python, во фреймы данных в Pandas?
14 ответов
Как говорит Уэс, io/sql read_sql сделает это, как только вы получите соединение с базой данных, используя DBI-совместимую библиотеку. Мы можем посмотреть на два коротких примера, используя MySQLdb
а также cx_Oracle
библиотеки для подключения к Oracle и MySQL и запроса их словарей данных. Вот пример для 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()
А вот эквивалентный пример для 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()
Для недавних читателей этого вопроса: у панд есть следующее предупреждение в их документах для версии 14.0:
Предупреждение: некоторые из существующих функций или псевдонимов функций устарели и будут удалены в будущих версиях. Это включает в себя: tquery, uquery, read_frame, frame_query, write_frame.
А также:
Предупреждение: поддержка разновидности "mysql" при использовании объектов соединения DBAPI устарела. MySQL будет дополнительно поддерживаться с движками SQLAlchemy (GH6900).
Это делает многие ответы здесь устаревшими. Вы должны использовать 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')
Для примера вот пример использования базы данных 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
Я предпочитаю создавать запросы с помощью SQLAlchemy, а затем создавать из них DataFrame. SQLAlchemy облегчает комбинирование условий SQL Python, если вы собираетесь смешивать и сопоставлять вещи снова и снова.
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)
Пример 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)
Тот же синтаксис работает и для Ms SQL-сервера, использующего 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()
И вот как вы подключаетесь к PostgreSQL с помощью драйвера psycopg2 (установите с помощью "apt-get install python-psycopg2", если вы работаете с производной ОС 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)
Для Sybase работает следующее (с http://python-sybase.sourceforge.net/)
import pandas.io.sql as psql
import Sybase
df = psql.frame_query("<Query>", con=Sybase.connect("<dsn>", "<user>", "<pwd>"))
pandas.io.sql.frame_query
устарела. использование pandas.read_sql
вместо.
импортировать модуль
import pandas as pd
import oursql
соединять
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
Это прекрасно работает и использует pandas.io.sql frame_works (с предупреждением об устаревании). База данных используется образец базы данных из учебника MySQL.
Для пользователей 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
Используя mysql.connector, вы можете написать что-то вроде этого:
import mysql.connector
import pandas as pd
# Database credentials
DB_HOST = 'host_ip'
DB_NAME = 'db_name or schema'
DB_USER = 'user_name'
DB_PASS = 'password'
try:
# Connect to the database
conn = mysql.connector.connect(
host=DB_HOST,
database=DB_NAME,
user=DB_USER,
password=DB_PASS
)
# Create a cursor object to execute SQL queries
cursor = conn.cursor()
# Example query
query = "SELECT * FROM your_table"
# Execute the query
cursor.execute(query)
# Fetch all the rows
rows = cursor.fetchall()
# Get column names
column_names = [desc[0] for desc in cursor.description]
# Create a DataFrame from the fetched rows and column names
df = pd.DataFrame(rows, columns=column_names)
# Process or analyze the DataFrame as needed
print(df)
# Close the cursor and connection
cursor.close()
conn.close()
except mysql.connector.Error as error:
print(f"Failed to connect to MySQL: {error}")
Это помогло мне подключиться к AWS MYSQL(RDS) из лямбда-функции на основеpython 3.x и загрузить в панду DataFrame
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
#}
Это должно работать просто отлично.
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))