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中类型说明
Integerint普通整数,一般是32位
SmallIntegerint取值范围小的整数,一般是16位
BigIntegerint或long不限制精度的整数
Floatfloat浮点数
Numericdecimal.Decimal普通整数,一般是32位
Stringstr变长字符串
Textstr变长字符串,对较长或不限长度的字符串做了优化
Unicodeunicode变长Unicode字符串
UnicodeTextunicode变长Unicode字符串,对较长或不限长度的字符串做了优化
Booleanbool布尔值
Datedatetime.date时间
Timedatetime.datetime日期和时间
LargeBinarystr二进制文件

常用的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='li@163.com',password='4526342',people_id=People.id)
people3 = People(name='sun',email='sun@163.com',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

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值