背景:上一篇文章可以看到,Python有了DB-API,编程贼方便,唯一的缺点就是需要程序员了解SQL(虽然在我看来这是必须的),但是就有的同学不愿意了解sql,而是更愿意操作Python对象,那怎么办?使用ORM呀~
ORM(Object relational mapper)指对象关系映射模型,展现了一种将用户定义的类映射到数据库中表的方法,将数据库的行映射为类的实例,将数据库字段映射为属性,开发同学只需要操作Python对象就能操作数据库,可以更加专注于业务逻辑的处理,提高开发效率。
但是ORM也有一定的缺点,它无法创建和删除数据库,一些复杂的数据库操作无法完成。
目前最知名的Python ORM是SQLAlchemy和SQLObject,两者均需要下载及安装 PyPI · The Python Package Index。SQLObject更简单,而SQLAlchemy中对象的抽象化十分完美,但是学习曲线较长,这里简单介绍下SQLAlchemy。
SQLAlchemy框架建立在数据库API之上,使用关系对象映射进行数据库操作,将对象转换成SQL,操作数据库API执行SQL并获取执行结果。大体流程分6步,如下:
1、连接数据库,不同数据库配置不同,调用的数据库API不同,格式为'数据库类型+数据库驱动名称://用户名:口令@机器地址:端口号/数据库名'。
MySQL-Python
mysql+mysqldb://:@[:]/
pymysql
mysql+pymysql://:@[:]/[?]
MySQL-Connector
mysql+mysqlconnector://:@[:]/
cx_Oracle
oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]
from sqlalchemy import *
engine=create_engine("mysql+mysqldb://user:pwd@ip:port/basename",echo=True,max_overflow=5)
echo=True会打印所有的状态变化,包括转换的SQL语句;max_overflow表示允许连接到数据库的最大连接数。
2、声明映射基类,将类映射到数据表,下面创建的数据库表结构类都要继承这个基类。
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
3、创建表结构类(类到数据库表的映射关系)
创建单个users表
from sqlalchemy import Column, Integer, String
class User(Base): #创建与数据库映射的表结构类,集成Base基类
__tablename__ = 'users' #必须包含的,表名称
id = Column(Integer, primary_key=True) #Column一列,primary_key也是必须包含的,表示主键,Integer类型
name = Column(String(10)) #属性类型string
passwd = Column(String(10))
创建一对多数据库表(一个学生只有一个班级,一个班级有多个学生)
#学生,有唯一的班级id
class Student(Base):
__tablename__ = 'student'
id = Column(Integer,primary_key=True)
name = Column(String(64),unique=True,nullable=False)
class_id=Column(Integer,ForeignKey('class.id'))
#班级有好多学生
class Classnumber(Base):
__tablename__ = 'class'
id = Column(Integer,primary_key=True,autoincrement=True)
classname = Column(String(64),unique=True,nullable=False)
创建多对多数据库表 (一个学生可以选多个课程,一个课程可以有多个学生)
#学生
class Student(Base):
__tablename__ = 'student'
id = Column(Integer,primary_key=True)
name = Column(String(64),unique=True,nullable=False)
#课程
class Course(Base):
__tablename__ = 'course'
id = Column(Integer,primary_key=True,autoincrement=True)
Coursename = Column(String(64),unique=True,nullable=False)
#可以表示课程和学生之间的多对多关系
class StudenttoCourse(Base):
__tablename__= 'studenttocourse'
id = Column(Integer,primary_key=True,autoincrement=True)
student_id = Column(Integer, ForeignKey('student.id'))
course_id = Column(Integer, ForeignKey('course.id'))
4、生成表,Base.metadata.create_all(engine),可重复生成,已有数据库表不会报错
5、创建会话,先创建与数据库对话的类Session = sessionmaker(bind=engine),实例化这个会话类session = Session()
6、实例化表结构类(数据库一行数据),在会话中操作该行数据
usertest = User(id=3,name='test', passwd='test') #实例化表结构类,数据库的一行数据
session.add(usertest) #添加该条记录
session.commit() #提交
整体代码示例:
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
engine=create_engine("mysql+mysqldb://user:pwd@ip:port/basename",echo=True,max_overflow=5)
Base = declarative_base() #表结构基类
from sqlalchemy import Column, Integer, String
class User(Base): #创建与数据库映射的表结构类,集成Base基类
__tablename__ = 'users' #必须包含的,表名称
id = Column(Integer, primary_key=True) #Column一列,primary_key也是必须包含的,表示主键,Integer类型
name = Column(String(10)) #属性类型string
passwd = Column(String(10))
Base.metadata.create_all(engine) #生成表
#创建会话(session)
Session = sessionmaker(bind=engine) #创建绑定该数据库连接的会话类
session = Session() #实例化会话类
usertest = User(id=3,name='test', passwd='test') #实例化表结构类,数据库的一行数据
session.add(usertest) #添加该条记录
session.commit() #提交
常用增删改查简单示例代码如下:
增:add添加单条、add_all多条记录(以list形式添加)
session.add(usertest1) #添加该条记录
session.add_all([usertest1,usertest2])#添加多条记录
查:query查询指定结果
data1=session.query(User.id,User.name,User.passwd).all()#表中所有数据,列表
data2=session.query(User.id,User.name).all()#表中所有数据的指定字段
data3=session.query(User.id,User.name,User.passwd).first()#第一个结果
data4=session.query(User.id,User.name,User.passwd).count()#数量
data5=session.query(User.id,User.name,User.passwd).offset(1).all()#从第2条数据开始读
data6=session.query(User.id,User.name,User.passwd).limit(1).all()#只显示前两条
data7=session.query(User.id,User.name,User.passwd).filter(User.id>1,User.name=='test').all()#过滤器根据条件查询
改:update更新数据库
data1=session.query(User).update({User.name:'wpp'})#更新数据
data2=session.query(User).filter(User.id==1).update({User.name:'ypp'})#更新指定数据
删:delete删除数据
data1=session.query(User).filter(User.id==1).delete()#删除指定数据
参考廖大神搭建ORM:Day 3 - 编写ORM - 廖雪峰的官方网站
加油加油~