Flask-数据库操作

前端之家收集整理的这篇文章主要介绍了Flask-数据库操作前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

一、什么是ORM

  • ORM 全拼Object-Relation Mapping. 称为对象-关系映射
  • 主要实现模型对象到关系数据库数据的映射.
    • 比如:把数据库表中每条记录映射为一个模型对象
    • @H_301_14@ @H_301_14@

      关系映射

      二、Flask-sqlAlchemy安装及设置

      1. 安装

      • 安装 flask-sqlalchemy
      • @H_301_14@
        pip install flask-sqlalchemy
        
        • 如果连接的是 MysqL 数据库,需要安装 MysqLdb
        • @H_301_14@
          pip install flask-MysqLdb
          

          提示: 如果flask-MysqLdb安装不上,推荐安装,pip install pyMysqL

          2. 数据库连接设置

          • 设置数据库链接地址,追踪信息
          • 格式:MysqL://<用户名>:<密码>@:<端口>/数据库名称
          • @H_301_14@
            # 数据库链接地址
            app.config['sqlALCHEMY_DATABASE_URI'] = 'MysqL://root:MysqL@127.0.0.1:3306/test'
            # 动态追踪修改设置,如未设置只会提示警告
            app.config['sqlALCHEMY_TRACK_MODIFICATIONS'] = True
            

            查看映射的sql语句,设置: app.config['sqlALCHEMY_ECHO'] = True

            • 配置完成需要去 MysqL 中创建项目所使用的数据库
            • @H_301_14@
              $ MysqL -uroot -pMysqL
              $ create database test charset utf8;
              
              from flask import Flask
              from flask_sqlalchemy import sqlAlchemy
              
              app = Flask(__name__)
              
              #2.设置数据库的配置信息
              #设置数据库链接信息,app.config["sqlALCHEMY_DATABASE_URI"] = "MysqL+pyMysqL://root:123456@127.0.0.1:3306/test"
              #该字段增加了大量的开销,会被禁用,建议设置为False
              app.config["sqlALCHEMY_TRACK_MODIFICATIONS"] = False
              
              
              #3.创建sqlalchemy对象db,关联app
              db = sqlAlchemy(app)
              
              # 4.编写模型类,字段,继承自db.Model
              class Student(db.Model):
                  __tablename__ = "students"
                  #主键,参数1: 表示id的类型,参数2: 表示id的约束类型
                  id = db.Column(db.Integer,primary_key=True)
                  name = db.Column(db.String(32))
              
              @app.route('/')
              def hello_world():
              
                  return "helloworld"
              
              if __name__ == '__main__':
              
                  #删除继承自db.Model的表
                  db.drop_all()
              
                  #5.创建数据库的表,创建的是继承自db.Model的表
                  db.create_all()
              
                  app.run(debug=True)
              

              三、数据库基本操作

              • 在Flask-sqlAlchemy中,插入、修改删除操作,均由数据库会话管理。
                • 会话用 db.session 表示。在准备把数据写入数据库前,要先将数据添加到会话中然后调用 db.session.commit() 方法提交会话。
                • @H_301_14@
                • 在 Flask-sqlAlchemy 中,查询操作是通过 query 对象操作数据。
                  • 最基本的查询是返回表中所有数据,可以通过过滤器进行更精确的数据库查询
                  • @H_301_14@ @H_301_14@

                    1. 增删改

                    """
                    增删改
                    
                    - 全部都是使用db.session操作
                    - 常见方法:
                      - db.session.add(obj) 添加单个对象
                      - db.session.add_all([obj1,obj2]) 添加多个对象
                      - db.session.delete(obj) 删除单个对象
                      - db.session.commit() 提交会话
                      - db.drop_all() 删除继承自db.Model所有表
                      - db.create_all() :创建继承自db.Model的所有表
                      - 其他:
                        - db.session.rollback() 回滚
                        - db.session.remove() 移除会话
                      - 案例: 编写两个模型类,一个角色模型类,还有一个用户模型类
                        - 关系: 一对多
                    
                    """
                    from flask import Flask
                    from flask_sqlalchemy import sqlAlchemy
                    
                    app = Flask(__name__)
                    
                    #1.设置数据库的配置信息
                    app.config["sqlALCHEMY_DATABASE_URI"] = "MysqL+pyMysqL://root:123456@127.0.0.1:3306/test"
                    app.config["sqlALCHEMY_TRACK_MODIFICATIONS"] = False
                    
                    #2.创建sqlalchemy对象,关联app
                    db = sqlAlchemy(app)
                    
                    #3.编写模型类
                    #角色(一方)
                    class Role(db.Model):
                        __tablename__ = "roles"
                        id = db.Column(db.Integer,primary_key=True)
                        name = db.Column(db.String(32))
                    
                        #如果一个类继承自object那么重写__str__方法即可,如果是继承自db.Model那么需要重写__repr__方法
                        def __repr__(self):
                            return "<Role:%s>"%self.name
                    
                    #用户(多方)
                    class User(db.Model):
                        __tablename__ = "users"
                        id = db.Column(db.Integer,primary_key=True)
                        name = db.Column(db.String(32))
                    
                        #建立外键
                        role_id = db.Column(db.Integer,db.ForeignKey(Role.id))
                    
                        #如果一个类继承自object那么重写__str__方法即可,如果是继承自db.Model那么需要重写__repr__方法
                        def __repr__(self):
                            return "<User:%s>"%self.name
                    
                    @app.route('/')
                    def hello_world():
                    
                        return "helloworld"
                    
                    if __name__ == '__main__':
                    
                        #为了演示方便,先删除表,后创建
                        db.drop_all()
                        db.create_all()
                    
                        app.run(debug=True)
                    
                    • @H_301_14@

                      使用ipython进行测试,前提是先进行安装

                      @H_403_179@

                      2. 查询

                      # -*- coding = utf-8 -*-
                      # @Time : 2020/10/2 10:15
                      # @Author : md
                      
                      '''
                      
                      查询练习
                      '''
                      
                      from flask import Flask
                      from flask_sqlalchemy import sqlAlchemy
                      
                      
                      app = Flask(__name__)
                      
                      
                      # 1.设置数据库的配置信息
                      app.config["sqlALCHEMY_DATABASE_URI"] = "MysqL+pyMysqL://root:123456@127.0.0.1:3306/test"
                      app.config["sqlALCHEMY_TRACK_MODIFICATIONS"] = False
                      # app.config["sqlALCHEMY_ECHO"] = True
                      
                      
                      # 2.创建sqlalchemy对象,关联app
                      db = sqlAlchemy(app)
                      
                      
                      # 3.编写模型类
                      # 角色(一方)
                      class Role(db.Model):
                          __tablename__ = "roles"
                          id = db.Column(db.Integer,primary_key=True)
                          name = db.Column(db.String(32))
                      
                          # 关系数据写在这个表中,也就是写在一方这个表中
                          # 为了查询方便,不会产生实体字段
                          # 给role添加了一个users属性,那么查询的方式是,role.users
                          # 给user添加了一个role属性,user.role
                      
                          # 重点 建立关系,这里的名字为想要建立关系的模型名字
                          # 解释:前半句话是给Role(本模型)模型添加一个users属性,因为这两个数据库通外键连接
                          # 所以,可以通过这个表的对象,就可以访问User表中的数据,例如:查看角色是admin的所有用户role.users
                          # 后半句是给本(自己)模型添加一个role属性,这样User表中的对象,就可以访问本表中的数据,可以知道某个用户是什么身份
                          # 例如查看用户的身份,user.role
                          # lazy="dynamic" 是懒加载
                          # backref反向引用
                          users = db.relationship("User",backref="role",lazy="dynamic")
                      
                          # 如果一个类继承自object那么重写__str__方法即可,如果是继承自db.Model那么需要重写__repr__方法
                          def __repr__(self):
                              return "<Role:%s>" % self.name
                      
                      
                      # 用户(多方)
                      class User(db.Model):
                          __tablename__ = "users"
                          id = db.Column(db.Integer,primary_key=True)
                          name = db.Column(db.String(32))
                          email = db.Column(db.String(32))
                          password = db.Column(db.String(32))
                      
                          # 建立外键
                          role_id = db.Column(db.Integer,db.ForeignKey(Role.id))
                      
                          # 如果一个类继承自object那么重写__str__方法即可,如果是继承自db.Model那么需要重写__repr__方法
                          def __repr__(self):
                              return "<User:%s,%s,%s>" % (self.id,self.name,self.email,self.password)
                      
                      @app.route('/')
                      def hello_world():
                      
                          return "helloworld"
                      
                      
                      if __name__ == '__main__':
                      
                          # 为了演示方便,后创建
                          db.drop_all()
                          db.create_all()
                      
                          # 创建测试数据
                          ro1 = Role(name='admin')
                          db.session.add(ro1)
                          db.session.commit()
                      
                          # 再次插入一条数据
                          ro2 = Role(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)
                      
                      • 其中realtionship描述了Role和User的关系。
                      • 第一个参数为对应参照的类"User"
                      • 第二个参数backref为类User,反向引用属性
                      • @H_301_14@

                        第三个参数lazy决定了什么时候sqlALchemy从数据库中加载数据

                        • 如果设置为子查询方式(subquery),则会在加载完Role对象后,就立即加载与其关联的对象,这样会让总查询数量减少,但如果返回的条目数量很多,就会比较慢
                          • 设置为 subquery 的话,role.users 返回所有数据列表
                          • @H_301_14@
                          • 另外,也可以设置为动态方式(dynamic),这样关联对象会在被使用的时候再进行加载,并且在返回前进行过滤,如果返回的对象数很多,或者未来会变得很多,那最好采用这种方式
                          • @H_301_14@

                            User.query.filter().all()

                            3. 查询练习

                            查询所有用户数据
                            User.query.filter().all()
                            此时过滤器可以不写
                            User.query.all()
                            
                            
                            查询有多少个用户
                            User.query.count()
                            
                            
                            
                            查询第1个用户
                            User.query.first()
                            
                            
                            查询id为4的用户[3种方式]
                            User.query.get(4) 此时get里面是主键
                            
                             User.query.filter(User.id == 4).all() 返回的是列表,但满足的只有一个
                            
                            User.query.filter(User.id == 4).first()
                            
                            User.query.filter_by(id=4).first()
                            
                            
                            
                            
                            查询名字结尾字符为g的所有数据[开始/结尾/包含]
                            User.query.filter(User.name.startswith('g')).all()
                            
                             User.query.filter(User.name.endswith('g')).all()
                            
                            User.query.filter(User.name.contains('g')).all()
                            
                            
                            查询名字不等于wang的所有数据
                            User.query.filter(User.name != 'wang').all()
                            
                            
                            查询名字和邮箱都以 li 开头的所有数据
                            User.query.filter(User.name.startswith('li'),User.email.startswith('li')).all()
                            
                            
                            查询password是 123456 或者 email 以 itheima.com 结尾的所有数据
                            from sqlalchemy import or_
                            User.query.filter(or_(User.password == '123456',User.email.endswith('itheima.com'))).all()
                            
                            
                            
                            查询id为 [1,3,5,7,9] 的用户列表
                            User.query.filter(User.id.in_([1,9])).all()
                            
                            
                            查询name为liu,的角色数据
                            user = User.name.filter(User.name == 'liu').first()
                            role = Role.query.filter(Role.id == user.role_id).first()
                            
                            
                            查询所有用户数据,并以邮箱排序
                             User.query.order_by(User.email).all()
                             User.query.order_by(User.email.desc()).all()
                            
                            
                            
                            
                            
                            每页3个,查询第2页的数据
                            
                            #page: 表示要查询的页数
                            #per_page: 表示每页有多少条数据
                            #Error_out: 建议写成False,查不到不会报错
                            paginate = User.query.paginate(page,per_page,Error_out)
                            
                            paginate.pages #总页数
                            paginate.page #当前页
                            paginate.items #当前的对象列表
                            
                            
                            查询前两条数据
                             User.query.limit(2).all()
                            
                            
                            

                            lazy="dynamic"

                            四、综合案例-图书管理

                            目的:

                            • 表单创建
                            • 数据库操作
                            • 一对多关系演练
                            • @H_301_14@

                              实现步骤:

                              • 1.创建数据库配置信息,定义模型类
                              • 2.创建数据库表,添加测试数据
                              • 3.编写html页面,展示数据
                              • 4.添加数据
                              • 5.删除书籍,删除作者
                              • @H_301_14@

                                1. 图书馆测试数据显示

                                • 步骤
                                  • 1.查询所有作者信息
                                  • 2.携带作者信息,渲染页面
                                  • @H_301_14@ @H_301_14@

                                    2. 图书馆添加数据

                                    • 添加的逻辑分析:
                                      • 1.如果作者存在,书籍存在,不能添加
                                      • 2.如果作者存在,书籍不存在,可以添加
                                      • 3.如果作者不存在,可以添加
                                      • @H_301_14@ @H_301_14@

                                        3. 图书馆删除书籍

                                        • 步骤
                                          • 1.根据书籍编号获取书籍对象
                                          • 2.删除书籍对象
                                          • 3.重定向页面展示
                                          • @H_301_14@ @H_301_14@

                                            4. 图书馆删除作者

                                            • 步骤
                                              • 1.根据作者编号获取作者对象
                                              • 2.遍历删除,作者书籍对象
                                              • 3.删除作者,提交数据库
                                              • 4.重定向页面展示
                                              • @H_301_14@ @H_301_14@

                                                5. 图书馆CSRFProtect应用

                                                • 作用: 防止csrf攻击的
                                                • 使用步骤:
                                                  • 1.导入类CSRFProtect
                                                  • 2.使用CSRFProtect保护app
                                                    • 一旦使用POST,PUT,DELTE,PATCH方式提交的时候就需要校验csrf_token
                                                    • @H_301_14@
                                                    • 3.需要设置SECRET_KEY,用来加密csrf_token
                                                    • 4.设置csrf_token到表单中
                                                    • @H_301_14@ @H_301_14@

                                                      6. 表单的创建

                                                      # -*- coding = utf-8 -*-
                                                      # @Time : 2020/10/2 16:07
                                                      # @Author : md
                                                      
                                                      
                                                      from flask import Flask,render_template,request,redirect,flash
                                                      from flask_sqlalchemy import sqlAlchemy
                                                      from flask_wtf.csrf import CSRFProtect
                                                      
                                                      app = Flask(__name__)
                                                      
                                                      # 由于使用了flash,所以得设置
                                                      app.config["SECRET_KEY"] = "wepricsjf"
                                                      
                                                      # 使用 CSRFProtect保护app
                                                      CSRFProtect(app)
                                                      
                                                      
                                                      # 1.设置数据库的配置信息
                                                      app.config["sqlALCHEMY_DATABASE_URI"] = "MysqL+pyMysqL://root:123456@127.0.0.1:3306/test"
                                                      app.config["sqlALCHEMY_TRACK_MODIFICATIONS"] = False
                                                      # 生成对应的sql语句在控制台
                                                      # app.config["sqlALCHEMY_ECHO"] = True
                                                      
                                                      
                                                      # 2.创建sqlalchemy对象,关联app
                                                      db = sqlAlchemy(app)
                                                      
                                                      
                                                      # 3.编写模型类
                                                      # 作者(一方)
                                                      class Author(db.Model):
                                                          __tablename__ = "authors"
                                                          id = db.Column(db.Integer,primary_key=True)
                                                          name = db.Column(db.String(32))
                                                      
                                                          # 关系数据,必须有外键为基础
                                                          books = db.relationship("Book",backref="author")
                                                      
                                                          # 如果一个类继承自object那么重写__str__方法即可,如果是继承自db.Model那么需要重写__repr__方法
                                                          def __repr__(self):
                                                              return "<Author:%s>" % self.name
                                                      
                                                      
                                                      # 书籍(多方)
                                                      class Book(db.Model):
                                                          __tablename__ = "books"
                                                          id = db.Column(db.Integer,primary_key=True)
                                                          name = db.Column(db.String(32))
                                                      
                                                          # 建立外键
                                                          author_id = db.Column(db.Integer,db.ForeignKey(Author.id))
                                                      
                                                          # 如果一个类继承自object那么重写__str__方法即可,如果是继承自db.Model那么需要重写__repr__方法
                                                          def __repr__(self):
                                                              return "<Book:%s,self.name)
                                                      
                                                      
                                                      # 5. 展示数据
                                                      @app.route('/')
                                                      def hello_world():
                                                          # 1. 查询所有的作者信息,因为作者有外键,可以通过关系数据方便的查出该作者对应的书籍
                                                          authors = Author.query.all()
                                                      
                                                          return render_template("library.html",authors=authors)
                                                      
                                                      
                                                      # 6. 添加数据
                                                      @app.route("/add_data",methods=["POST"])
                                                      def add_data():
                                                          # 1. 获取提交的数据
                                                          author_name = request.form.get("author")
                                                          book_name = request.form.get("book")
                                                      
                                                          # 先判断输入的内容是否为空
                                                          if not all([author_name,book_name]):
                                                              flash("作者或书籍不能为空")
                                                              return redirect("/")
                                                      
                                                      
                                                          # 2. 根据作者信息查询作者对象
                                                          author = Author.query.filter(Author.name == author_name).first()
                                                          # 3. 判断作者是否存在
                                                          if author:
                                                              # 4. 通过书籍名称查询书籍对象,并且这本书的作者的id和查询出来的作者的id一样
                                                              # 也就是查看要添加的这本书是不是该作者写的
                                                              book = Book.query.filter(Book.name == book_name,Book.author_id == Author.id).first()
                                                              # 5. 判断书籍是否存在
                                                              if book:
                                                                  # return "该作者已经写了这本书了"
                                                                  flash("已经有该作者写的这本书了")
                                                              else:
                                                                  # 创建书籍对象,添加数据库
                                                                  book = Book(name=book_name,author_id=author.id)
                                                                  db.session.add(book)
                                                                  db.session.commit()
                                                          else:
                                                              # 作者不存在也是可以添加的
                                                              # 先在作者表中进行添加
                                                              author = Author(name=author_name)
                                                              db.session.add(author)
                                                              db.session.commit()
                                                      
                                                              # 然后再书籍表中进行添加
                                                              book = Book(name=book_name,author_id=author.id)
                                                              db.session.add(book)
                                                              db.session.commit()
                                                      
                                                          # 6. 重定向首页
                                                          return redirect("/")
                                                      
                                                      
                                                      # 7. 删除书籍
                                                      @app.route("/delete_book/<int:book_id>")
                                                      def delete_book(book_id):
                                                          # 1. 根据id获取到书籍对象
                                                          book = Book.query.get(book_id)
                                                          # 2. 删除这个书籍
                                                          db.session.delete(book)
                                                          db.session.commit()
                                                          # 3. 重定向页面
                                                          return redirect("/")
                                                      
                                                      
                                                      # 7. 删除作者
                                                      @app.route("/delete_author/<int:author_id>")
                                                      def delete_author(author_id):
                                                          # 1. 根据id获取到作者对象
                                                          author = Author.query.get(author_id)
                                                          # 2. 这个作者的全部书籍,由于使用了关系数据,直接这样写就可以
                                                          books = author.books
                                                          # 3. 遍历这个作者的全部书籍
                                                          for book in books:
                                                              db.session.delete(book)
                                                          # 4. 删除作者
                                                          db.session.delete(author)
                                                          db.session.commit()
                                                      
                                                          # 5. 重定向页面
                                                          return redirect("/")
                                                      
                                                      
                                                      if __name__ == '__main__':
                                                          # 为了演示方便,先删除后创建
                                                          db.drop_all()
                                                          db.create_all()
                                                      
                                                          # 4. 添加测试数据库
                                                          # 生成数据
                                                          au1 = Author(name='老王')
                                                          au2 = Author(name='老尹')
                                                          au3 = Author(name='老刘')
                                                          # 把数据提交给用户会话
                                                          db.session.add_all([au1,au2,au3])
                                                          # 提交会话
                                                          db.session.commit()
                                                      
                                                          bk1 = Book(name='老王回忆录',author_id=au1.id)
                                                          bk2 = Book(name='我读书少,你别骗我',author_id=au1.id)
                                                          bk3 = Book(name='如何才能让自己更骚',author_id=au2.id)
                                                          bk4 = Book(name='怎样征服美丽少女',author_id=au3.id)
                                                          bk5 = Book(name='如何征服英俊少男',author_id=au3.id)
                                                          # 把数据提交给用户会话
                                                          db.session.add_all([bk1,bk2,bk3,bk4,bk5])
                                                          # 提交会话
                                                          db.session.commit()
                                                      
                                                          app.run()
                                                      

                                                      7. library.html

                                                      <!DOCTYPE html>
                                                      <html lang="en">
                                                      <head>
                                                          <Meta charset="UTF-8">
                                                          <title>Title</title>
                                                      </head>
                                                      <body>
                                                      
                                                      {# action: 提交到的地址,method: 表示提交的方式 #}
                                                      <form action="/add_data" method="post">
                                                      {# 设置隐藏字段csrf_token,只要使用了CSRFProtect,然后使用模板渲染的时候就可以直接使用csrf_token()方法#}
                                                          <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
                                                      
                                                          作者: <input type="text" name="author"><br>
                                                          书籍: <input type="text" name="book"><br>
                                                          <input type="submit" value="添加"><br>
                                                          {% for message in get_flashed_messages() %}
                                                              <span style="color: red;">{{ message }}</span>
                                                          {% endfor %}
                                                      </form>
                                                      
                                                      <hr>
                                                      
                                                      {# 数据展示 #}
                                                      <ul>
                                                          {# 遍历作者 #}
                                                          {% for author in authors %}
                                                      {#        <li>作者: {{ author.name }}</li>#}
                                                      {#        <li>作者: {{ author.name }} <a href="/delete_author/{{ author.id }}">删除</a></li>#}
                                                              <li>作者: {{ author.name }} <a href="{{ url_for("delete_author",author_id=author.id) }}">删除</a></li>
                                                      
                                                              {# 遍历作者的书籍 #}
                                                              <ul>
                                                                  {% for book in author.books %}
                                                      {#                <li>书籍: {{ book.name }} </li>#}
                                                                      <li>书籍: {{ book.name }} <a href="/delete_book/{{ book.id }}">删除</a></li>
                                                                  {% endfor %}
                                                      
                                                              </ul>
                                                          {% endfor %}
                                                      
                                                      </ul>
                                                      
                                                      
                                                      
                                                      </body>
                                                      </html>
                                                      

                                                      五、多对多

                                                      在项目开发过程中,会遇到很多数据之间多对多关系的情况,比如:

                                                      • 学生网上选课(学生和课程)
                                                      • 老师与其授课的班级(老师和班级)
                                                      • 用户与其收藏的新闻(用户和新闻)
                                                      • 等等...
                                                      • @H_301_14@

                                                        所以在开发过程中需要使用 ORM 模型将表与表的多对多关联关系使用代码描述出来。多对多关系描述有一个唯一的点就是:需要添加一张单独的表去记录两张表之间的对应关系

                                                        1. 需求分析

                                                        • 学生可以网上选课,学生有多个,课程也有多个
                                                        • 学生有:张三、李四、王五
                                                        • 课程有:物理、化学、生物
                                                        • 选修关系有:
                                                          • 张三选修了化学和生物
                                                          • 李四选修了化学
                                                          • 王五选修了物理、化学和生物
                                                          • @H_301_14@ @H_301_14@

                                                            需求:

                                                            1. 查询某个学生选修了哪些课程
                                                            2. 查询某个课程都有哪些学生选择

                                                            2. 代码

                                                            # -*- coding = utf-8 -*-
                                                            # @Time : 2020/10/2 19:30
                                                            # @Author : md
                                                            
                                                            
                                                            '''
                                                            多对多,学生和课程
                                                            '''
                                                            
                                                            from flask import Flask
                                                            from flask_sqlalchemy import sqlAlchemy
                                                            
                                                            
                                                            app = Flask(__name__)
                                                            
                                                            
                                                            # 1.设置数据库的配置信息
                                                            app.config["sqlALCHEMY_DATABASE_URI"] = "MysqL+pyMysqL://root:123456@127.0.0.1:3306/test"
                                                            app.config["sqlALCHEMY_TRACK_MODIFICATIONS"] = False
                                                            # app.config["sqlALCHEMY_ECHO"] = True
                                                            
                                                            
                                                            # 2.创建sqlalchemy对象,关联app
                                                            db = sqlAlchemy(app)
                                                            
                                                            
                                                            # 3.编写模型类
                                                            # 学生
                                                            class Student(db.Model):
                                                                __tablename__ = "students"
                                                                id = db.Column(db.Integer,使用在多对多中的时候注意secondary这个属性,是中间表的表名,用来二次查询
                                                                courses = db.relationship("Course",backref="students",secondary="td_student_course")
                                                            
                                                                # 如果一个类继承自object那么重写__str__方法即可,如果是继承自db.Model那么需要重写__repr__方法
                                                                def __repr__(self):
                                                                    return "<Role:%s>" % self.name
                                                            
                                                            
                                                            # 课程
                                                            class Course(db.Model):
                                                                __tablename__ = "courses"
                                                                id = db.Column(db.Integer,primary_key=True)
                                                                name = db.Column(db.String(32))
                                                            
                                                                # 如果一个类继承自object那么重写__str__方法即可,如果是继承自db.Model那么需要重写__repr__方法
                                                                def __repr__(self):
                                                                    return "<User:%s>" % self.name
                                                            
                                                            
                                                            # 中间表
                                                            db.Table(
                                                                "td_student_course",db.Column("student_id",db.Integer,db.ForeignKey(Student.id)),db.Column("course_id",db.ForeignKey(Course.id))
                                                            )
                                                            
                                                            @app.route('/')
                                                            def hello_world():
                                                            
                                                                return "helloworld"
                                                            
                                                            
                                                            
                                                            # 为了演示,先删除后创建
                                                            db.drop_all()
                                                            db.create_all()
                                                            
                                                            stu1 = Student(name='张三')
                                                            stu2 = Student(name='李四')
                                                            stu3 = Student(name='王五')
                                                            
                                                            cou1 = Course(name='物理')
                                                            cou2 = Course(name='化学')
                                                            cou3 = Course(name='生物')
                                                            
                                                            stu1.courses = [cou2,cou3]
                                                            stu2.courses = [cou2]
                                                            stu3.courses = [cou1,cou2,cou3]
                                                            
                                                            db.session.add_all([stu1,stu2,stu2])
                                                            db.session.add_all([cou1,cou3])
                                                            
                                                            db.session.commit()
                                                            
                                                            
                                                            if __name__ == '__main__':
                                                                app.run()
                                                            
                                                            

                                                            六、数据库迁移

                                                            • 目的: 当数据库的表结构发生变化之后,如果直接删除原有的数据,再添加新的数据,有可能导致数据丢失
                                                            • 注意点:
                                                              • 1.是为了备份表结构,而不是数据
                                                              • 2.如果想要备份数据,需要使用工具,navicat,MysqLworkbench,等等
                                                              • 3.更新的过程数据一般不会丢失,做降级的时候需要谨慎操作
                                                              • @H_301_14@
                                                              • 操作流程:
                                                                • 1.安装扩展
                                                                  • pip install flask_script
                                                                  • pip install flask_migrate
                                                                  • @H_301_14@
                                                                  • 2.导入三个类
                                                                    • from flask_script import Manager
                                                                    • from flask_migrate import Migrate,MigrateCommand
                                                                    • @H_301_14@
                                                                    • 3.通过Manager类创建对象manager,管理app
                                                                      • manager = Manager(app)
                                                                      • @H_301_14@
                                                                      • 4.使用Migrate,关联db,app
                                                                        • Migrate(app,db)
                                                                        • @H_301_14@
                                                                        • 5.给manager添加一条操作命令
                                                                          • manager.add_command("db",MigrateCommand)
                                                                          • @H_301_14@
                                                                          • 相关迁移命令:
                                                                            • 生成迁移文件夹[一次就好]
                                                                              • python xxx.py db init
                                                                              • @H_301_14@
                                                                              • 将模型类生成迁移脚本[重复执行]
                                                                                • python xxx.py db migrate -m '注释'
                                                                                • @H_301_14@
                                                                                • 将迁移脚本更新到数据库中[重复执行]
                                                                                  • python xxx.py db upgrade/downgrade [version]
                                                                                  • @H_301_14@
                                                                                  • 其他命令
                                                                                    • 查看最新版本的命令
                                                                                      • python xxx.py db show
                                                                                      • @H_301_14@
                                                                                      • 查看当前版本
                                                                                        • python xxx.py db current
                                                                                        • @H_301_14@
                                                                                        • 查看所有的历史版本
                                                                                          • python xxx.py db history
                                                                                          • @H_301_14@ @H_301_14@ @H_301_14@ @H_301_14@ @H_301_14@
                                                                                            # -*- coding = utf-8 -*-
                                                                                            # @Time : 2020/10/2 20:38
                                                                                            # @Author : md
                                                                                            
                                                                                            from flask import Flask
                                                                                            from flask_script import Manager
                                                                                            from flask_migrate import Migrate,MigrateCommand
                                                                                            from flask_sqlalchemy import sqlAlchemy
                                                                                            
                                                                                            app = Flask(__name__)
                                                                                            
                                                                                            # 设置数据库配置信息
                                                                                            app.config["sqlALCHEMY_DATABASE_URI"] = "MysqL+pyMysqL://root:123456@localhost:3306/test1"
                                                                                            app.config["sqlALCHEMY_TRACK_MODIFICATIONS"] = False
                                                                                            
                                                                                            # 创建sqlAlchemy对象,关联app
                                                                                            db = sqlAlchemy(app)
                                                                                            
                                                                                            
                                                                                            # 3. 通过Manager类创建对象manager,管理app
                                                                                            manager = Manager(app)
                                                                                            
                                                                                            # 4.使用Migrate,app
                                                                                            Migrate(app,db)
                                                                                            
                                                                                            # 5.给manager添加一条操作命令
                                                                                            manager.add_command("db",MigrateCommand)
                                                                                            
                                                                                            
                                                                                            # 6.编写模型类
                                                                                            class Student(db.Model):
                                                                                                id = db.Column(db.Integer,primary_key=True)
                                                                                                name = db.Column(db.String(32))
                                                                                                age = db.Column(db.Integer)
                                                                                               # email = db.Column(db.String(32))
                                                                                            
                                                                                            
                                                                                            @app.route('/')
                                                                                            def hello_world():
                                                                                                return "helloworld"
                                                                                            
                                                                                            
                                                                                            if __name__ == '__main__':
                                                                                                manager.run()
                                                                                            

                                                                                            生成迁移文件

                                                                                            将模型类生成迁移脚本

                                                                                            将迁移脚本更新到数据库

                                                                                            此时就可以在数据库中看到对应的表了

                                                                                            此时在代码中多写一行,添加一列

                                                                                            然后继续执行这两条命令,就会看到数据表结构中就多了一列

                                                                                            还可以进行降级

                                                                                            然后再升级到指定的版本

猜你在找的Flask相关文章