python 数据库编程进阶—ORM

背景:上一篇文章可以看到,Python有了DB-API,编程贼方便,唯一的缺点就是需要程序员了解SQL(虽然在我看来这是必须的),但是就有的同学不愿意了解sql,而是更愿意操作Python对象,那怎么办?使用ORM呀~

一、什么是ORM?

ORM(Object relational mapper)指对象关系映射模型,展现了一种将用户定义的类映射到数据库中表的方法,将数据库的行映射为类的实例,将数据库字段映射为属性,开发同学只需要操作Python对象就能操作数据库,可以更加专注于业务逻辑的处理,提高开发效率。

但是ORM也有一定的缺点,它无法创建和删除数据库,一些复杂的数据库操作无法完成。

二、常见ORM框架

目前最知名的Python ORM是SQLAlchemy和SQLObject,两者均需要下载及安装 PyPI · The Python Package Index。SQLObject更简单,而SQLAlchemy中对象的抽象化十分完美,但是学习曲线较长,这里简单介绍下SQLAlchemy。

python 数据库编程进阶—ORM_第1张图片

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

参考廖大神搭建ORM:Day 3 - 编写ORM - 廖雪峰的官方网站

加油加油~

你可能感兴趣的:(Python,数据库,python,mysql)