Работа с данными из базы данных SQL



До этого момента, мы получали данные только из csv файлов. Это довольно распространённый способ сохранения данных, но далеко не единственный! Pandas может работать с данными из HTML, JSON, SQL, Excel (!!!), HDF5, Stata, и некоторых других вещей. В этой части мы поговорим о работе с данными из баз данных SQL.

In [1]:
import pandas as pd
import sqlite3

Чтение из SQL баз данных

Загрузить данные из SQL базы можно с помощью функции pd.read_sql. read_sql автоматически преобразует столбцы SQL в столбцы DataFrame.

read_sql принимает 2 аргумента: запрос SELECT, и connection. Это здорово, так как это означает, что можно читать из любого вида базы данных - неважно, MySQL, SQLite, PostgreSQL, или другая.

В этом примере мы читаем из базы SQLite, но другие читаются точно также. Файл, с которым мы будем работать.

In [2]:
con = sqlite3.connect("data/weather_2012.sqlite")
df = pd.read_sql("SELECT * from weather_2012 LIMIT 3", con)
df
Out[2]:
id date_time temp
0 1 2012-01-01 00:00:00 -1.8
1 2 2012-01-01 01:00:00 -1.8
2 3 2012-01-01 02:00:00 -1.8

read_sql не устанавливает первичный ключ (id) в качестве индекса. Можно это сделать вручную, добавив аргумент index_col к read_sql.

Если вы много использовали read_csv, вы могли заметить, что у него также есть аргумент index_col. И ведёт он себя точно так же.

In [3]:
df = pd.read_sql("SELECT * from weather_2012 LIMIT 3", con, index_col='id')
df
Out[3]:
date_time temp
id
1 2012-01-01 00:00:00 -1.8
2 2012-01-01 01:00:00 -1.8
3 2012-01-01 02:00:00 -1.8

Если вы хотите, чтобы dataframe был индексирован несколькими столбцами, в index_col можно указать их список:

In [4]:
df = pd.read_sql("SELECT * from weather_2012 LIMIT 3", con,
                 index_col=['id', 'date_time'])
df
Out[4]:
temp
id date_time
1 2012-01-01 00:00:00 -1.8
2 2012-01-01 01:00:00 -1.8
3 2012-01-01 02:00:00 -1.8

Запись в базу

Запись производится с помощью метода to_sql (по аналогии с CSV):

In [5]:
weather_df = pd.read_csv('data/weather_2012.csv')
con = sqlite3.connect("data/test_db.sqlite")
con.execute("DROP TABLE IF EXISTS weather_2012")
weather_df.to_sql("weather_2012", con)
Out[5]:
/usr/local/lib/python3.5/dist-packages/pandas/core/generic.py:1345: UserWarning: The spaces in these column names will not be changed. In pandas versions < 0.14, spaces were converted to underscores.
  chunksize=chunksize, dtype=dtype)

Теперь мы можем загрузить записанные данные:

In [6]:
con = sqlite3.connect("data/test_db.sqlite")
df = pd.read_sql("SELECT * from weather_2012 LIMIT 3", con)
df
Out[6]:
index Date/Time Temp (C) Dew Point Temp (C) Rel Hum (%) Wind Spd (km/h) Visibility (km) Stn Press (kPa) Weather
0 0 2012-01-01 00:00:00 -1.8 -3.9 86 4 8.0 101.24 Fog
1 1 2012-01-01 01:00:00 -1.8 -3.7 87 4 8.0 101.24 Fog
2 2 2012-01-01 02:00:00 -1.8 -3.4 89 7 4.0 101.26 Freezing Drizzle,Fog

Главное преимущество хранения данных в базе в том, что можно напрямую делать SQL запросы. Это особенно хорошо, если SQL для вас более родной язык. Например, можно отсортировать по колонке 'Weather' с помощью лишь SQL:

In [7]:
con = sqlite3.connect("data/test_db.sqlite")
df = pd.read_sql("SELECT * from weather_2012 ORDER BY Weather LIMIT 3", con)
df
Out[7]:
index Date/Time Temp (C) Dew Point Temp (C) Rel Hum (%) Wind Spd (km/h) Visibility (km) Stn Press (kPa) Weather
0 67 2012-01-03 19:00:00 -16.9 -24.8 50 24 25.0 101.74 Clear
1 114 2012-01-05 18:00:00 -7.1 -14.4 56 11 25.0 100.71 Clear
2 115 2012-01-05 19:00:00 -9.2 -15.4 61 7 25.0 100.80 Clear

Другие базы данных

Для подключения к MySQL:

Чтобы это работало, у вас на машине должна быть установлена соответствующая база данных

In [ ]:
import MySQLdb
con = MySQLdb.connect(host="localhost", db="test")

PostgreSQL:

In [ ]:
import psycopg2
con = psycopg2.connect(host="localhost")