在实际工作中,大多数的数据都是存储在数据库中的。pandas 提供了读取与存储关系型数据库数据的函数。除了 pandas 库外,还需要使用 SQLAlchemy 库建立对应的数据库连接。SQLAlchemy 配合相应数据库的 Python 连接工具(例如,MySQL 数据库需要安装 mysqlclient 或者 pymysql 库,Oracle 数据库需要安装 cx_oracle 库)。
可使用 create_engine 函数建立一个数据库连接。pandas 支持 MySQL、PostgreSQL、Oracle、SQL Server 和 SQLite 等主流数据库。下面以 MySQL 数据库为例,介绍 pandas 的读/写数据库文件的操作。
SQLAlchemy 连接 MySQL 数据库
1) ORM 介绍
ORM(Object Relational Mapping,对象关系映射)可将数据库中的表与面向对象语言中的类建立一种对应关系。当操作数据库时,数据库中的表或者表中的一条记录就可以直接通过操作类或者类实例来完成,ORM 相当于把数据库也给实例化了。
ORM 的优点如下:
隐藏了数据访问细节,使数据库的交互变得简单易行,并且完全不用考虑 SQL 语句;
ORM 使构造固化数据结构变得简单易行。
2) SQLAlchemy 安装
SQLAlchemy 是 Python 社区最知名的 ORM 工具之一,使用它可以实现高效和高性能的数据库访问。在 Windows 下安装 SQLAlchemy 方法,进入 cmd 状态,输入以下命令:
pip install SQLAlchemy
pip install pymysql
注意:由于 MySQL 数据库不支持 Python 3 版本,所以要用 pymysql 与 SQLAlchemy 交互。
3) 创建 MySQL 数据库
创建一个 MySQL 数据库,数据库名为 salary。在该数据库下创建一个员工月工资收入表(salary),表的结构包括姓名、性别、年龄和月工资,然后再输入 10 条员工月工资收入的记录,记录的内容可自拟。
4) 连接数据库
编写连接数据库的程序代码 db_link.py 如下。
# -*- coding: utf-8 -*-
from sqlalchemy import create_engine
# 创建实例,并连接salary库
engine = create_engine('mysql+pymysql://root:@localhost:3306/salary?charset=gb2312')
print(engine)
运行该程序,如果输出下面信息,即表明数据库连接成功。
Engine(mysql+pymysql://root:***@localhost:3306/salary?charset=gb2312)
在连接数据库的程序中,create_engine 中输入的是一个连接字符串。在使用 Python 的 SQLAlchemy 时,MySQL 和 Oracle 数据库连接字符串的格式如下:
数据库产品名+连接工具名://用户名:密码@数据库 IP 地址:数据库端口号/数据库名称? charset=数据库数据编码
读取数据库文件
pandas 提供了 3 个读取数据库文件的函数,它们的作用如下:
read_sql() 函数:既可读取数据库中的某个表,又可实现查询操作;
read_sql_table() 函数:只能读取数据库的某一个表格,不能实现查询操作;
read_sql_query() 函数:可实现查询操作,但不能直接读取数据库中的某个表。
read_sql() 函数的语法格式如下:
pandas.read_sql(sql, con, index_col=None, coerce_float=True, columns=None)
read_sql_table() 函数的语法格式如下:
pandas.read_sql_table(table_name, con, schema=None, index_col=None, coerce_float=True, columns=None)
read_sql_query() 函数的语法格式如下:
pandas.read_sql_query(sql, con, index_col=None, coerce_float=True)
函数中的参数说明如下:
sql:接收 string,表示读取数据库的表名或者 SQL 语句,无默认值;
table_name:接收 string,表示读取数据库的表名,无默认值;
con:接收数据库连接。表示接收数据库连接信息,无默认值;
index_col:接收 int、sequence 或 False,表示设定的列作为行名。如果是一个数列,则是多重索引,默认为 None;
coerce_float:接收 boolean。将数据库中的 decimal 类型的数据转换为 pandas 中的 float64 类型的数据,默认为 True;
columns:接收 int,表示读取数据的列名,默认为 None。
【例 1 】以员工月工资收入信息为例,分别运用 read_sql()、read_sql_table() 和 read_sql_query() 函数读取 MySQL 数据库文件 salary,并观察这 3 个函数的特点。
示例代码 test1.py 如下。
# -*- coding: utf-8 -*-
import pandas as pd
from sqlalchemy import create_engine
# 创建实例,并连接salary库
engine = create_engine('mysql+pymysql://root:@localhost:3306/salary?charset=gb2312')
print(engine)
#使用read_sql_query()查看数据表的数目
tables = pd.read_sql_query('show tables',con=engine)
print('salary数据库数据表的清单:','\n',tables)
#使用read_sql_table()读取salary数据表的数据
dftable = pd.read_sql_table('salary',con=engine)
print('salary数据表的数据:','\n',dftable)
#使用read_sql()读取salary数据表的数据
dftable = pd.read_sql('SELECT * FROM 'salary'',con=engine)
print('salary数据表的数据:','\n',dftable)
存储为数据库数据
将 DataFrame 写入数据库中,同样也要依赖 SQLAlchemy 库的 create_engine 函数创建数据库连接。将数据存储到数据库的函数是 to_sql(),其函数的语法格式如下:
DataFrame.to_sql(name,con, schema=None, if_exists='fail', index=True, index_label=None, dtype=None)
函数中的参数说明如下:
name:接收 string,表示数据库的表名,无默认值;
con:接收数据库连接,表示接收数据库连接信息,无默认值;
if_exists:接收 fail、replace 和 append。fail 表示如果表名存在,则不执行写入操作;replace 表示如果存在,则将原数据库表删除,再重新创建;append 则表示在原数据库表的基础上追加数据,默认为 fail;
index:接收 boolean,表示是否将行索引作为数据传入数据库,默认为 True;
index_label:接收 string 或者 sequence,代表是否引用索引的名称,如果 index 参数为 True,此参数为 None,则使用默认名称。如果为多重索引,则必须使用 sequence,默认为 None;
dtype:接收 dict,代表写入的数据类型(列名为 key,数据格式为 values),默认为 None。
【例 2 】以员工月工资收入信息为例,首先读取 salary.csv 文件,然后将读取的数据存储到 salary 数据库的 salary 数据表中。
示例代码 test2.py 如下。
# -*- coding: utf-8 -*-
import pandas as pd
from sqlalchemy import create_engine
# 创建实例,并连接salary库
engine = create_engine('mysql+pymysql://root:@localhost:3306/salary?charset=gb2312')
print('数据文件保存在d盘的data目录下,读取csv文件')
df = pd.read_csv('d:\data\salary.csv',encoding='GBK')
print('将读取csv文件中数据存储到salary数据表中')
df.to_sql('salary.',con=engine,if_exists='replace')