当前位置:Gxlcms > 数据库问题 > python框架之Flask基础篇(二)-------- 数据库的操作

python框架之Flask基础篇(二)-------- 数据库的操作

时间:2021-07-01 10:21:17 帮助过:10人阅读

  • 配置config属性,连接数据库:

    app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:mysql@localhost/first_flask"
    app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

  • 创建数据库first_flask
  • 创建操作数据库对象:db = SQLAlchemy(app)
  • 下面直接上代码解释:

     

    # -*- coding:utf-8 -*-
    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    
    app = Flask(__name__)
    # url的格式为:数据库的协议://用户名:密码@ip地址:端口号(默认可以不写)/数据库名
    app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:mysql@localhost/first_flask"
    # 动态追踪数据库的修改. 性能不好. 且未来版本中会移除. 目前只是为了解决控制台的提示才写的
    app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
    # 创建数据库的操作对象
    db = SQLAlchemy(app)
    
    
    class Role(db.Model):
    
        __tablename__ = "roles"
        id = db.Column(db.Integer,primary_key=True)
        name = db.Column(db.String(16),unique=True)
        # 给Role类创建一个uses属性,关联users表。
        # backref是反向的给User类创建一个role属性,关联roles表。这是flask特殊的属性。
        users = db.relationship(User,backref="role")
        # 相当于__str__方法。
        def __repr__(self):
            return "Role: %s %s" % (self.id,self.name)
    
    
    class User(db.Model):
        # 给表重新定义一个名称,默认名称是类名的小写,比如该类默认的表名是user。
        __tablename__ = "users"
        id = db.Column(db.Integer,primary_key=True)
        name = db.Column(db.String(16),unique=True)
        email = db.Column(db.String(32),unique=True)
        password = db.Column(db.String(16))
        # 创建一个外键,和django不一样。flask需要指定具体的字段创建外键,不能根据类名创建外键
        role_id = db.Column(db.Integer,db.ForeignKey("roles.id"))
    
        def __repr__(self):
            return "User: %s %s %s %s" % (self.id,self.name,self.password,self.role_id)
    
    
    @app.route(/)
    def hello_world():
        return Hello World!
    
    
    if __name__ == __main__:
        # 删除所有的表
        db.drop_all()
        # 创建表
        db.create_all()
    
        ro1 = Role(name = "admin")
        # 先将ro1对象添加到会话中,可以回滚。
        db.session.add(ro1)
        
        ro2 = Role()
        ro2.name = user
        db.session.add(ro2)
        # 最后插入完数据一定要提交
        db.session.commit()
    
        us1 = User(name=wang, email=wang@163.com, password=123456, role_id=ro1.id)
        us2 = User(name=zhang, email=zhang@189.com, password=201512, role_id=ro2.id)
        us3 = User(name=chen, email=chen@126.com, password=987654, role_id=ro2.id)
        us4 = User(name=zhou, email=zhou@163.com, password=456789, role_id=ro1.id)
        us5 = User(name=tang, email=tang@itheima.com, password=158104, role_id=ro2.id)
        us6 = User(name=wu, email=wu@gmail.com, password=5623514, role_id=ro2.id)
        us7 = User(name=qian, email=qian@gmail.com, password=1543567, role_id=ro1.id)
        us8 = User(name=liu, email=liu@itheima.com, password=867322, role_id=ro1.id)
        us9 = User(name=li, email=li@163.com, password=4526342, role_id=ro2.id)
        us10 = User(name=sun, email=sun@163.com, password=235523, role_id=ro2.id)
        db.session.add_all([us1, us2, us3, us4, us5, us6, us7, us8, us9, us10])
        db.session.commit()
        app.run(debug=True)

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    下面插播一条bug:

    当把表格创建完成,注释这两句话:

     # 删除所有的表
        db.drop_all()
        # 创建表
        db.create_all()

    然后向表格里面插入数据,此时会出现这样的错误:

    sqlalchemy.exc.IntegrityError: (_mysql_exceptions.IntegrityError) (1062, "Duplicate entry ‘admin‘ for key ‘name‘") [SQL: u‘INSERT INTO roles (name) VALUES (%s)‘] [parameters: (‘admin‘,)]

    查了网上的好多资料说把字段的约束unique=True去掉就好了,但是根本原因不在这。

    原因就是因为app.run(debug=True)。开启debug模式之后,当我们修改代码的时候,比如将删除表和创建表这两句话注释,然后打开插入数据的注释。这个过程debug模式默认就已经把程序运行一遍了。此时数据库就已经有了数据,当我们再次手动执行的时候,又往数据库中插入了一条数据,这时候就会报错。因为字段的约束是唯一性的unique,所以解决的办法有两种:

    第一种:就是不要将删除表和创建表这两句话注释,每次执行都要带着这两个句话。无论是debug模式自动执行还是我们手动执行程序,都会先删除表然后再创建表,所以执行多少次都不怕。

    第二种:关闭debug模式。就是这样app.run()

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    2.数据库的增删改查:

    1.以下的方法都是返回一个新的查询,需要配合执行器使用。

    filter(): 过滤,功能比较强大。
    filter_by():过滤,用在一些比较简单的过滤场景。

    order_by():排序。默认是升序,降序需要导包:from sqlalchemy import * 。然后引入desc方法。比如order_by(desc("email")).按照邮箱字母的降序排序。

     

    group_by():分组。

    2.以下都是一些常用的执行器:配合上面的过滤器使用。

    get():获得id等于几的函数。比如:查询id=1的对象。get(1)。切记:括号里没有“id=”,直接传入id的数值就ok。因为该函数的功能就是查询主键等于几的对象。

    all():查询所有的数据。

    first():查询第一个数据。

    count():返回查询结果的数量。

    paginate():分页查询,返回一个分页对象。paginate(参数1,参数2,参数3)

    参数1:当前是第几页,参数2:每页显示几条记录,参数3:是否要返回错误。

    返回的分页对象有三个属性:items:获得查询的结果,pages:获得一共有多少页,page:获得当前页。

    3.常用的逻辑符:

    需要倒入包才能用的有:from sqlalchemy import * 

    not_  and_  or_   还有上面说的排序desc。

    常用的内置的有:in_      表示某个字段在什么范围之中。

    4.其他关系的一些数据库查询:

    endswith():以什么结尾。

    startswith():以什么开头。

    contains():包含

    5.下面体会一下上面的这些用法:

    1. 查询所有用户数据
    User.query.all()
    2. 查询有多少个用户
    User.query.count()
    3. 查询第1个用户
    User.query.first()
    
    4. 查询id为4的用户[3种方式]
    User.query.get(4)
    User.query.filter_by(id=4).first()    
    User.query.filter(User.id==4).first()
    
    filter:(类名.属性名==)
    filter_by:(属性名=)
    
    filter_by: 用于查询简单的列名,不支持比较运算符
    filter比filter_by的功能更强大,支持比较运算符,支持or_、in_等语法。
    
    
    5. 查询名字结尾字符为g的所有数据[开始/包含]
    User.query.filter(User.name.endswith(g)).all()
    User.query.filter(User.name.contains(‘g‘)).all()
    
    6. 查询名字不等于wang的所有数据[2种方式]
     from sqlalchemy import not_
    注意了啊:逻辑查询的格式逻辑符_(类属性其他的一些判断) User.query.filter(not_(User.name
    ==‘wang‘)).all() User.query.filter(User.name!=wang).all() 7. 查询名字和邮箱都以 li 开头的所有数据[2种方式] from sqlalchemy import and_ User.query.filter(and_(User.name.startswith(li), User.email.startswith(li))).all() User.query.filter(User.name.startswith(li), User.email.startswith(li)).all() 8. 查询password是 `123456` 或者 `email` 以 `itheima.com` 结尾的所有数据 from sqlalchemy import or_ User.query.filter(or_(User.password==123456, User.email.endswith(itheima.com))).all() 9. 查询id为 [1, 3, 5, 7, 9] 的用户列表 User.query.filter(User.id.in_([1, 3, 5, 7, 9])).all() 10. 查询name为liu的角色数据 关系引用 User.query.filter_by(name=liu).first().role.name 11. 查询所有用户数据,并以邮箱排序 排序 User.query.order_by(email).all() 默认升序 User.query.order_by(desc(‘email‘)).all() 降序 12. 查询第2页的数据, 每页只显示3条数据 help(User.query.paginate) 三个参数: 1. 当前要查询的页数 2. 每页的数量 3. 是否要返回错误 pages = User.query.paginate(2, 3, False) pages.items # 获取查询的结果 pages.pages # 总页数 pages.page # 当前页数

     

    python框架之Flask基础篇(二)-------- 数据库的操作

    标签:网上   model   引入   用户   根据   prim   增删改   sql   contain   

    人气教程排行