ORM(对象关系映射)的介绍以及在flask中的使用

1.ORM简介

ORM是object realation mapping的简写,也就是对象关系映射。主要实现模型对象到关系数据库数据的映射。

那么我们为何要使用ORM呢?

优点 :

  • 只需要面向对象编程, 不需要面向数据库编写代码.
    • 对数据库的操作都转化成对类属性和方法的操作.
    • 不用编写各种数据库的sql语句.
  • 实现了数据模型与数据库的解耦, 屏蔽了不同数据库操作上的差异.
    • 不在关注用的是mysqloracle...等.
    • 通过简单的配置就可以轻松更换数据库, 而不需要修改代码.

缺点 :

  • 相比较直接使用SQL语句操作数据库,有性能损失.
  • 根据对象的操作转换成SQL语句,根据查询的结果转化成对象, 在映射过程中有性能损失.

2. ORM在Flask中的使用

在flask中我们使用flask-sqlalchemy来实现模型对象关系的映射。

SQLALchemy 是对数据库的抽象,让开发者不用直接和 SQL 语句打交道,而是通过 Python 对象来操作数据库,在舍弃一些性能开销的同时,换来的是开发效率的较大提升(上边已经介绍过了)

flask-sqlalchemy 是一个简化了 SQLAlchemy 操作的flask扩展。

①在使用ORM之前要进行一系列的配置:数据库链接配置,链接时常的配置等(这里不在介绍,可进行自我查阅)

②配置结束以后就可以通过模型类操作数据库了

下面我们学习通过模型类操作数据库的方法:

常用的SQLAlchemy字段类型

类型名 python中类型 说明
Integer int 普通整数,一般是32位
SmallInteger int 取值范围小的整数,一般是16位
BigInteger int或long 不限制精度的整数
Float float 浮点数
Numeric decimal.Decimal 普通整数,一般是32位
String str 变长字符串
Text str 变长字符串,对较长或不限长度的字符串做了优化
Unicode unicode 变长Unicode字符串
UnicodeText unicode 变长Unicode字符串,对较长或不限长度的字符串做了优化
Boolean bool 布尔值
Date datetime.date 时间
Time datetime.datetime 日期和时间
LargeBinary str 二进制文件

常用的SQLAlchemy列选项

选项名 说明
primary_key 如果为True,代表表的主键
unique 如果为True,代表这列不允许出现重复的值
index 如果为True,为这列创建索引,提高查询效率
nullable 如果为True,允许有空值,如果为False,不允许有空值
default 为这列定义默认值

常用的SQLAlchemy关系选项

选项名 说明
backref 在关系的另一模型中添加反向引用
primary join 明确指定两个模型之间使用的联结条件
uselist 如果为False,不使用列表,而使用标量值
order_by 指定关系中记录的排序方式
secondary 指定多对多关系中关系表的名字
secondary join 在SQLAlchemy中无法自行决定时,指定多对多关系中的二级联结条件

下面我们就可以使用ORM,看看不使用SQL语句如何操作数据库

db = SQLAlchemy(app)

class People(db.Model):
    # 表名
    __tablename__ = 'People'
    # 列对象
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    us = db.relationship('User', backref='role', lazy='dynamic')

    #repr()方法用于显示一个可读字符串
    def __repr__(self):
        return 'Role:%s'% self.name

 有了模型类,下面就可以创建表并插入数据啦:

 建表:db.create_all() 

 附加:删表(db.drop_all())

#插入一条数据
people1 = People(name='fenghua')
db.session.add(people1)
db.session.commit()

#插入多条数据
people2 = People(name='li',email='[email protected]',password='4526342',people_id=People.id)
people3 = People(name='sun',email='[email protected]',password='235523',people_id=People.id)
db.session.add_all([people2, people3])
db.session.commit()

有了数据就能进行对数据操作了,下面了解常用操作:

常用的SQLAlchemy查询过滤器

过滤器 说明
filter() 把过滤器添加到原查询上,返回一个新查询
filter_by() 把等值过滤器添加到原查询上,返回一个新查询
limit 使用指定的值限定原查询返回的结果
offset() 偏移原查询返回的结果,返回一个新查询
order_by() 根据指定条件对原查询结果进行排序,返回一个新查询
group_by() 根据指定条件对原查询结果进行分组,返回一个新查询

常用的SQLAlchemy查询执行器

方法 说明
all() 以列表形式返回查询的所有结果
first() 返回查询的第一个结果,如果未查到,返回None
first_or_404() 返回查询的第一个结果,如果未查到,返回404
get() 返回指定主键对应的行,如不存在,返回None
get_or_404() 返回指定主键对应的行,如不存在,返回404
count() 返回查询结果的数量
paginate() 返回一个Paginate对象,它包含指定范围内的结果

在Flask-SQLAlchemy中,插入、修改、删除操作,均由数据库会话管理。

会话用 db.session 表示。在准备把数据写入数据库前,要先将数据添加到会话中然后调用 commit() 方法提交会话。

在 Flask-SQLAlchemy 中,查询操作是通过 query 对象操作数据。

最基本的查询是返回表中所有数据,可以通过过滤器进行更精确的数据库查询。

查询:filter_by精确查询

返回名字等于wang的所有人

People.query.filter_by(name='wang').all()

first()返回查询到的第一个对象

User.query.first()

all()返回查询到的所有对象

User.query.all()

filter模糊查询,返回名字结尾字符为g的所有数据。

User.query.filter(User.name.endswith('g')).all()

get():参数为主键,如果主键不存在没有返回内容

User.query.get()

逻辑非,返回名字不等于wang的所有数据

User.query.filter(User.name!='wang').all()

not_ 相当于取反

from sqlalchemy import not_
User.query.filter(not_(User.name=='chen')).all()

逻辑与,需要导入and,返回and()条件满足的所有数据

from sqlalchemy import and_
User.query.filter(and_(User.name!='wang',User.email.endswith('163.com'))).all()

逻辑或,需要导入or_

from sqlalchemy import or_
User.query.filter(or_(User.name!='wang',User.email.endswith('163.com'))).all()

查询数据后删除

user = User.query.first()
db.session.delete(user)
db.session.commit()
User.query.all()

更新数据

user = User.query.first()
user.name = 'dong'
db.session.commit()

关联查询示例(假设角色于用户是1对多的关系)重点!!!

一个角色可以有多个用户,一个用户只能属于一个角色。

class Role(db.Model):
    ...
    #关键代码
    us = db.relationship('User', backref='role', lazy='dynamic')
    ...

class User(db.Model):
    ...
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

  查询角色的所有用户

#查询roles表id为1的角色
ro1 = Role.query.get(1)
#查询该角色的所有用户
ro1.us.all() 

这里的us就是模型里边设置的us,当用1查多时使用1对象.relationship返回对象.过滤器.执行器 进行查找

反之多查1时使用多方的对象.backref字段.过滤器.执行器 进行查找

  查询用户的角色

#查询users表id为3的用户
us1 = User.query.get(3)
#查询用户属于什么角色
us1.role

猜你喜欢

转载自blog.csdn.net/weixin_31449201/article/details/81737963