flask-sqlalchemy的数据库操作

本文详细介绍了Python中使用ORM(对象关系映射)进行数据库操作的方法,包括增删查改四大操作。通过实例展示了如何创建对象、设置属性、查询过滤、排序、限制和更新数据。同时,讲解了一对多和多对多的关系映射,以及如何处理多表关联查询。这些内容对于Python后端开发人员在实际项目中管理数据库十分关键。
摘要由CSDN通过智能技术生成

一、增

# 1.实例化对象。
#变量名 = 模版名() 例如:
user = User()
#定义对象的各个属性 例如:
user.username = username
user.password = hashlib.sha256(password.encode('utf-8')).hexdigest()
user.phone = phone
# 添加并提交
db.session.add(user)   # 类似于将对象数据保存在一个缓冲区中
db.session.commit()    # 将数据提交到数据库

二、查

1.查询所有: 模型类.query.all()          ------------->           select * from user;

2.有条件的查询:

         1)模型类.query.filter_by(字段名 = 值)           ----->          select * from user where 字段=值;

         2)模型类.query.filter_by(字段名 = 值).first()          ------->          select * from user where 字段=值 limit(1);

        3)模型类.query.filter()    #里面是布尔的条件(条件判断语句) 后边要跟 .all() 或者 .first 来确定查询的数量                         例如:模型类.query.filter(模型名.字段名 == 值)

        4)模型类.query.filter().all() ----->  一个列表

             模型类.query.filter().first() -----> 一个对象

        例如:

              (1)  User.query.filter(User.username.endswith('z')).all()    ------->    select * from user where username like '%z';

              (2) User.query.filter(User.username.startswith('z')).all()    ------>    select * from user where username like 'z%';

              (3) User.query.filter(User.username.contains('z')).all()    -------->    select * from user where username like '%z%';

              (4) User.query.filter(User.username.like('z%')     ------>    elect * from user where username like 'z%';

              (5) User.query.filter(User.username.ilike('z%').      ilike不区分大小写

多条件:

                from sqlalchemy import or_, and_,not_

                并且: and_          获取: or_          非: not_

              (6) User.query.filter(or_(User.username.like('z%'), User.username.contains('i'))).all()     ---------->      select * from user where username like 'z%' or username like '%i%';

              (7) User.query.filter(and_(User.username.contains('i'), User.rdatetime.__gt__('2020-05-25 10:30:00'))).all()    ------>    select * from user where username like '%i%' and rdatetime < '2020-05-25 10:30:00'

                补充:__gt__,__lt__,__ge__(gt equal : >= ),__le__ (le equal : <= ) --->   通常应用在范围(整型,日期) 也可以直接使用 > < >= <= !=

              (8) User.query.filter(not_(User.username.contains('i'))).all()        # 查询所有用户名不包含“i”的

              (9) user_list = User.query.filter(User.phone.in_(['15810106788','13801011299'])).all()  -----> select * from user where phone in ['15810106788','13801011299'];     # 查找手机号是‘15810106788’或‘13801011299’的所有人

              (10) User.age.between(15,30)   ----->     # 年龄在15到30之间

排序:order_by

              先筛选再排序

              (11) user_list = User.query.filter(User.username.contains('z')).order_by(-User.rdatetime).all()   ------>    # 在User.rdatetime的前面加了‘ - ’ 表示以此降序排列,默认是升序排列

              (12) user_list = User.query.order_by(-User.id).all()        # 以主键id降序排列

             注意:order_by(参数):

                1.直接是字符串: '字段名'      但是不能倒序

                2.填字段名: 模型.字段          order_by(-模型.字段)    倒序

限制: limit    (一般和offset一起使用)

              (13) user_list = User.query.limit(2).all()    # 默认获取前两条

              (14) user_list = User.query.offset(2).limit(2).all()   # offset(2)表示偏移两个,即此语句为:跳过2条记录再获取两条记录          

 三、改

变量名 = 模型类.query.get(xxx)  # 通过主键获取数据对象

变量名.字段名 = xxxx        # 对对象的指定字段的值进行修改

# 提交更改

db.session.commit()        # 提交修改

 四、删

1.逻辑删除(定义数据库中的表的时候,添加一个字段isdelete,通过此字段控制是否删除)

变量名 = 模型类.query.get(xx)        # 通过主键获取数据对象

变量名.isdelete = True        # 在表中定义一个名为isdelete的字段值为布尔类型,当对数据对象进行删除时,将其值改为True,在进行查询显示是增加对isdelete字段的筛选

db.session.commit()        # 提交修改

2.物理删除(彻底从数据库中删掉)

变量名 = 模型类.query.get(id)        # 通过主键获取数据对象

db.session.delete(变量名)        # 类似于缓存删除数据

db.session.commit()        # 提交删除

五、关系

主要理解多张数据库表的关系。

明确:一个项目肯定会有多张表,确定表与表之间的关系最重要。 在开始项目前必须要确定表与表的关系

单独一张表: User 是不行的。user要与其他的建立联系。

以student和班级clazz为例: 一个班级是有多名学生的

如果是sql语句:

  1. 查询python01班级的学生

select * from student where 班级=(select id from clazz where 班级名=‘python01’)
或者
select * from student inner join clazz on student.班级=clazz.id where clazz.班级名='python01' 

     2.查询xiaowang所在的班级名 

select 班级名 from clazz where id= (select 班级 from student where name='xiaowang')
或者
select 班级名 from student inner join clazz on student.班级=clazz.id where name='xiaowang'

但是体现在python框架中不方便直接写表连接查询和子查询。python框架为了简化多表的查询,制定了多表的关系:

1.一对多

常见的比如:班级对学生,部门对员工,学校对班级,用户对文章,用户对订单

可以说一个班级有多名同学或者一个部门有多名员工,但是不能说:

一一个员工属于多个部门,一个班级属于多个学校....

在flask的框架中如何体现1对多的模型关系?

就是通过外键ForignKey和relationship体现。ForignKey是给映射关系说的,relationship是给模板使用的。

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(15), nullable=False)
    password = db.Column(db.String(64), nullable=False)
    phone = db.Column(db.String(11), unique=True, nullable=False)
    email = db.Column(db.String(30))
    icon = db.Column(db.String(100))
    isdelete = db.Column(db.Boolean, default=False)
    rdatetime = db.Column(db.DateTime, default=datetime.now)
    # 增加一个字段
    articles = db.relationship('Article', backref='user')
    #
    def __str__(self):
        return self.username
from datetime import datetime

from exts import db


class Article(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(50), nullable=False)
    content = db.Column(db.Text, nullable=False)
    pdatetime = db.Column(db.DateTime, default=datetime.now)
    click_num = db.Column(db.Integer, default=0)
    save_num = db.Column(db.Integer, default=0)
    love_num = db.Column(db.Integer, default=0)
    # 外键 同步到数据库的外键关系
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

2.多对多

常见的多对多:用户对文章评论,用户对商品,学生对课程

一个用户可以买多个商品,反过来这个个学生属于多个班级,商品的还可以让多个用户购买

用户 1 -----》 n 商品 n 《----- 1

一个学生可以选择多门课程,反过来一门课程还可以让多个学生选择

....

 以用户和商品为例:

from exts import db


class User(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(15), nullable=False)
    password = db.Column(db.String(64), nullable=False)
    phone = db.Column(db.String(11), unique=True, nullable=False)
    email = db.Column(db.String(30))
    icon = db.Column(db.String(100))
    isdelete = db.Column(db.Boolean, default=False)
    rdatetime = db.Column(db.DateTime, default=datetime.now)
    # 增加一个字段不会体现在数据库中,只是一个关系
    articles = db.relationship('Article', backref='user')   # 用于根据文章找用户  db.relationship('建立关系的模型类名', backref='反向引用时要用的名')  backref 反向引用


class Goods(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    gname = db.Column(db.String(100), nullable=False)
    price = db.Column(db.Float, nullable=False)
    # back reference
    users = db.relationship('User', backref='goodslist', secondary='user_goods')

    def __str__(self):
        return self.gname
      

# 关系表: user与goods之间的关系
class User_goods(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    goods_id = db.Column(db.Integer, db.ForeignKey('goods.id'))
    number = db.Column(db.Integer, default=1)

实例中users = db.relationship('User', backref='goodslist', secondary='user_goods')的User为模型类名,user_goods为关系表名,backref='goodslist'用于当得知用户去查找购买的商品时,goodslist可以随便区但当反向查找是一定要用在此定义的名字

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值