library.py
1""" 2分析图书馆案例 3 4- 1.数据库配置 5 - 作者模型(一方) 6 - 书籍模型(多方) 7- 2.添加测试数据 8- 3.添加作者,书籍 9- 4.删除作者,删除书籍 10 11""" 12from flask import Flask, render_template, request, redirect,flash 13from flask_sqlalchemy import SQLAlchemy 14from flask_wtf.csrf import CSRFProtect 15 16app = Flask(__name__) 17 18app.config["SECRET_KEY"] = "fdfdfd" 19 20#使用CSRFProtect保护app 21CSRFProtect(app) 22 23#1.设置数据库配置信息 24app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@127.0.0.1:3306/library36" 25app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False 26# app.config["SQLALCHEMY_ECHO"] = True #写上之后会在控制台输出对应生成的sql语句 27 28#2.创建SQLAlchemy对象,关联app 29db = SQLAlchemy(app) 30 31#3.编写模型类 32#作者模型(一方) 33class Author(db.Model): 34 __tablename__ = "authors" 35 id = db.Column(db.Integer,primary_key=True) 36 name = db.Column(db.String(32)) 37 38 #关系属性 39 books = db.relationship("Book",backref="author") 40 41#书籍模型(多方) 42class Book(db.Model): 43 __tablename__ = "books" 44 id = db.Column(db.Integer,primary_key=True) 45 name = db.Column(db.String(32)) 46 47 #外键 48 author_id = db.Column(db.Integer,db.ForeignKey(Author.id)) 49 # author_id = db.Column(db.Integer,db.ForeignKey("authors.id")) #和上面的方式等价 50 51 52#4.展示页面 53@app.route('/') 54def show_index(): 55 #1.查询所有的作者信息 56 authors = Author.query.all() 57 58 #2.携带作者信息,渲染页面 59 return render_template("file01library.html",authors=authors) 60 61#5.添加数据 62@app.route('/add_data', methods=["POST"]) 63def add_data(): 64 #1.获取提交的数据 65 author_name = request.form.get("author") 66 book_name = request.form.get("book") 67 68 #1.1判断输入的内容是否为空 69 if not all([author_name,book_name]): 70 flash("作者或者书籍不能为空") 71 return redirect("/") 72 73 #2.根据作者的信息,查询作者对象 74 author = Author.query.filter(Author.name == author_name).first() 75 76 #3.判断作者是否存在 77 if author: 78 79 #4.通过书籍名称查询书籍对象, 获取该作者,有没有写过该书 80 book = Book.query.filter(Book.name == book_name,Book.author_id == author.id).first() 81 82 #5.判断书籍对象是否存在 83 if book: 84 flash("该作者,有该书了") 85 else: 86 #创建书籍对象,添加到数据库 87 book = Book(name=book_name,author_id=author.id) 88 db.session.add(book) 89 db.session.commit() 90 else: 91 #创建作者,对象,添加到书籍库 92 author = Author(name=author_name) 93 db.session.add(author) 94 db.session.commit() 95 96 # 创建书籍对象,添加到数据库 97 book = Book(name=book_name, author_id=author.id) 98 db.session.add(book) 99 db.session.commit() 100 101 #6.重定向到首页展示 102 return redirect("/") 103 104#6.删除书籍 105@app.route('/delete_book/<int:book_id>') 106def delete_book(book_id): 107 #1.根据书籍编号取出书籍对象 108 book = Book.query.get(book_id) 109 110 #2.删除书籍 111 db.session.delete(book) 112 db.session.commit() 113 114 #3.重定向到页面显示 115 return redirect("/") 116 117#7.删除作者 118@app.route('/delete_author/<int:author_id>') 119def delete_author(author_id): 120 #1.根据作者编号取出作者对象 121 author = Author.query.get(author_id) 122 123 #2.遍历作者书籍,删除 124 for book in author.books: 125 db.session.delete(book) 126 127 #3.删除作者,提交数据库 128 db.session.delete(author) 129 db.session.commit() 130 131 #4.重定向展示页面 132 return redirect("/") 133 134 135if __name__ == '__main__': 136 #为了演示方便,先删除,后创建 137 db.drop_all() 138 db.create_all() 139 140 #添加测试数据库 141 # 生成数据 142 au1 = Author(name='老王') 143 au2 = Author(name='老尹') 144 au3 = Author(name='老刘') 145 # 把数据提交给用户会话 146 db.session.add_all([au1, au2, au3]) 147 # 提交会话 148 db.session.commit() 149 150 151 bk1 = Book(name='老王回忆录', author_id=au1.id) 152 bk2 = Book(name='我读书少,你别骗我', author_id=au1.id) 153 bk3 = Book(name='如何才能让自己更骚', author_id=au2.id) 154 bk4 = Book(name='怎样征服美丽少女', author_id=au3.id) 155 bk5 = Book(name='如何征服英俊少男', author_id=au3.id) 156 # 把数据提交给用户会话 157 db.session.add_all([bk1, bk2, bk3, bk4, bk5]) 158 # 提交会话 159 db.session.commit() 160 161 162 app.run(debug=True)
library.html
1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6</head> 7<body> 8 9{# action: 提交到的地址, method: 表示提交的方式 #} 10<form action="/add_data" method="post"> 11 12 {# 设置隐藏字段csrf_token , 只要使用了CSRFProtect,然后使用模板渲染的时候就可以直接使用csrf_token()方法#} 13 <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> 14 15 作者: <input type="text" name="author"><br> 16 书籍: <input type="text" name="book"><br> 17 <input type="submit" value="添加"><br> 18 {% for message in get_flashed_messages() %} 19 <span style="color: red;">{{ message }}</span> 20 {% endfor %} 21 22</form> 23 24<hr> 25 26{# 数据展示 #} 27<ul> 28 {# 遍历作者 #} 29 {% for author in authors %} 30{# <li>作者: {{ author.name }} <a href="/delete_author/{{ author.id }}">删除</a></li>#} 31 <li>作者: {{ author.name }} <a href="{{ url_for("delete_author",author_id=author.id) }}">删除</a></li> 32 33 {# 遍历作者的书籍 #} 34 <ul> 35 {% for book in author.books %} 36 <li>书籍: {{ book.name }} <a href="/delete_book/{{ book.id }}">删除</a></li> 37 {% endfor %} 38 39 </ul> 40 {% endfor %} 41 42</ul> 43 44 45 46</body> 47</html>
ORM相关操作流程
orm.py
1""" 2操作流程: 3 4- 1.安装扩展 5 - pip install flask_sqlalchemy 6 - pip install flask_mysqldb / pymysql 7- 2.设置数据库的配置信息 8- 3.创建sqlalchemy对象db,关联app 9- 4.编写模型类,字段,继承自db.Model, 10- 5.操作数据库 11 - 增删改 12 - 查询 13""" 14from flask import Flask 15from flask_sqlalchemy import SQLAlchemy 16 17app = Flask(__name__) 18 19#2.设置数据库的配置信息 20#设置数据库的链接信息, 21app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@127.0.0.1:3306/data36" 22#该字段增加了大量的开销,会被禁用,建议设置为False 23app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False 24 25 26#3.创建sqlalchemy对象db,关联app 27db = SQLAlchemy(app) 28 29# 4.编写模型类,字段,继承自db.Model 30class Student(db.Model): 31 __tablename__ = "students" 32 #主键, 参数1: 表示id的类型, 参数2: 表示id的约束类型 33 id = db.Column(db.Integer,primary_key=True) 34 name = db.Column(db.String(32)) 35 36@app.route('/') 37def hello_world(): 38 39 return "helloworld" 40 41if __name__ == '__main__': 42 43 #删除继承自db.Model的表 44 db.drop_all() 45 46 #5.创建数据库的表,创建的是继承自db.Model的表 47 db.create_all() 48 49 app.run(debug=True)
数据库的增删改
role_user.py
1""" 2增删改 3 4- 全部都是使用db.session操作 5- 常见方法: 6 - db.session.add(obj) 添加单个对象 7 - db.session.add_all([obj1,obj2]) 添加多个对象 8 - db.session.delete(obj) 删除单个对象 9 - db.session.commit() 提交会话 10 - db.drop_all() 删除继承自db.Model所有表 11 - db.create_all() :创建继承自db.Model的所有表 12 - 其他: 13 - db.session.rollback() 回滚 14 - db.session.remove() 移除会话 15 - 案例: 编写两个模型类, 一个角色模型类, 还有一个用户模型类 16 - 关系: 一对多 17 18""" 19from flask import Flask 20from flask_sqlalchemy import SQLAlchemy 21 22app = Flask(__name__) 23 24#1.设置数据库的配置信息 25app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@127.0.0.1:3306/data36" 26app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False 27 28#2.创建SQLalchemy对象,关联app 29db = SQLAlchemy(app) 30 31#3.编写模型类 32#角色(一方) 33class Role(db.Model): 34 __tablename__ = "roles" 35 id = db.Column(db.Integer,primary_key=True) 36 name = db.Column(db.String(32)) 37 38 #如果一个类继承自object那么重写__str__方法即可, 如果是继承自db.Model那么需要重写__repr__方法 39 def __repr__(self): 40 return "<Role:%s>"%self.name 41 42#用户(多方) 43class User(db.Model): 44 __tablename__ = "users" 45 id = db.Column(db.Integer,primary_key=True) 46 name = db.Column(db.String(32)) 47 48 #建立外键 49 role_id = db.Column(db.Integer,db.ForeignKey(Role.id)) 50 51 #如果一个类继承自object那么重写__str__方法即可, 如果是继承自db.Model那么需要重写__repr__方法 52 def __repr__(self): 53 return "<User:%s>"%self.name 54 55@app.route('/') 56def hello_world(): 57 58 return "helloworld" 59 60if __name__ == '__main__': 61 62 #为了演示方便,先删除表,后创建 63 db.drop_all() 64 db.create_all() 65 66 app.run(debug=True)
数据库的查询
role_user_query.py
1""" 2查询 3 4""" 5from flask import Flask 6from flask_sqlalchemy import SQLAlchemy 7 8app = Flask(__name__) 9 10#1.设置数据库的配置信息 11app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@127.0.0.1:3306/data37" 12app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False 13app.config["SQLALCHEMY_ECHO"] = True 14 15#2.创建SQLalchemy对象,关联app 16db = SQLAlchemy(app) 17 18#3.编写模型类 19#角色(一方) 20class Role(db.Model): 21 __tablename__ = "roles" 22 id = db.Column(db.Integer,primary_key=True) 23 name = db.Column(db.String(32)) 24 25 #给role添加了一个users属性, 那么查询的方式是, role.users 26 #给user添加了一个role属性, 那么查询的方式是, user.role 27 users = db.relationship("User",backref="role",lazy="dynamic") 28 29 #如果一个类继承自object那么重写__str__方法即可, 如果是继承自db.Model那么需要重写__repr__方法 30 def __repr__(self): 31 return "<Role:%s>"%self.name 32 33#用户(多方) 34class User(db.Model): 35 __tablename__ = "users" 36 id = db.Column(db.Integer,primary_key=True) 37 name = db.Column(db.String(32)) 38 email = db.Column(db.String(32)) 39 password = db.Column(db.String(32)) 40 41 #建立外键 42 role_id = db.Column(db.Integer,db.ForeignKey(Role.id)) 43 44 #如果一个类继承自object那么重写__str__方法即可, 如果是继承自db.Model那么需要重写__repr__方法 45 def __repr__(self): 46 return "<User:%s,%s,%s,%s>"%(self.id,self.name,self.email,self.password) 47 48@app.route('/') 49def hello_world(): 50 51 return "helloworld" 52 53if __name__ == '__main__': 54 55 #为了演示方便,先删除表,后创建 56 db.drop_all() 57 db.create_all() 58 59 # 创建测试数据 60 ro1 = Role(name='admin') 61 db.session.add(ro1) 62 db.session.commit() 63 64 # 再次插入一条数据 65 ro2 = Role(name='user') 66 db.session.add(ro2) 67 db.session.commit() 68 69 # 多条用户数据 70 us1 = User(name='wang', email='wang@163.com', password='123456', role_id=ro1.id) 71 us2 = User(name='zhang', email='zhang@189.com', password='201512', role_id=ro2.id) 72 us3 = User(name='chen', email='chen@126.com', password='987654', role_id=ro2.id) 73 us4 = User(name='zhou', email='zhou@163.com', password='456789', role_id=ro1.id) 74 us5 = User(name='tang', email='tang@itheima.com', password='158104', role_id=ro2.id) 75 us6 = User(name='wu', email='wu@gmail.com', password='5623514', role_id=ro2.id) 76 us7 = User(name='qian', email='qian@gmail.com', password='1543567', role_id=ro1.id) 77 us8 = User(name='liu', email='liu@itheima.com', password='867322', role_id=ro1.id) 78 us9 = User(name='li', email='li@163.com', password='4526342', role_id=ro2.id) 79 us10 = User(name='sun', email='sun@163.com', password='235523', role_id=ro2.id) 80 db.session.add_all([us1, us2, us3, us4, us5, us6, us7, us8, us9, us10]) 81 db.session.commit() 82 83 app.run(debug=True)
多对多关系
many_to_many.py
1""" 2多对多关系 3案例: 学生和课程 4""" 5from flask import Flask 6from flask_sqlalchemy import SQLAlchemy 7 8app = Flask(__name__) 9 10#1.设置数据库的配置信息 11app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@localhost:3306/data38" 12app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False 13 14#2.创建Sqlalchemy对象,关联app 15db = SQLAlchemy(app) 16 17#3.编写模型类 18 19#中间表 20tb_student_course = db.Table( 21 "tb_student_course", 22 db.Column("student_id",db.Integer,db.ForeignKey("students.id")), 23 db.Column("course_id",db.Integer,db.ForeignKey("courses.id")) 24) 25 26#学生 27class Student(db.Model): 28 __tablename__ = "students" 29 id = db.Column(db.Integer,primary_key=True,autoincrement=True) 30 name = db.Column(db.String(32)) 31 32 #关系属性secondary: 使用在多对多种,用来表示二次查询的 33 courses = db.relationship("Course",backref="students",secondary="tb_student_course") 34 35 36 #为了方便输出对象查看,重写__repr__方法 37 def __repr__(self): 38 return "<Student:%s>"%self.name 39 40#课程 41class Course(db.Model): 42 __tablename__ = "courses" 43 id = db.Column(db.Integer,primary_key=True,autoincrement=True) 44 name = db.Column(db.String(32)) 45 46 #为了方便输出对象查看,重写__repr__方法 47 def __repr__(self): 48 return "<Student:%s>"%self.name 49 50 51@app.route('/') 52def hello_world(): 53 54 return "helloworld" 55 56if __name__ == '__main__': 57 58 #为了演示方便,先删除,后创建 59 db.drop_all() 60 db.create_all() 61 62 # 添加测试数据 63 stu1 = Student(name='张三') 64 stu2 = Student(name='李四') 65 stu3 = Student(name='王五') 66 67 cou1 = Course(name='物理') 68 cou2 = Course(name='化学') 69 cou3 = Course(name='生物') 70 71 stu1.courses = [cou2, cou3] 72 stu2.courses = [cou2] 73 stu3.courses = [cou1, cou2, cou3] 74 75 db.session.add_all([stu1, stu2, stu2]) 76 db.session.add_all([cou1, cou2, cou3]) 77 78 db.session.commit() 79 80 81 app.run(debug=True)
数据库迁移
flask_migrate.py
1""" 2数据库迁移[掌握] 3 4- 目的: 当数据库的表结构发生变化之后,如果直接删除原有的数据,再添加新的数据,有可能导致数据丢失 5- 注意点: 6 - 1.是为了备份表结构,而不是数据 7 - 2.如果想要备份数据,需要使用工具,navicat,mysqlworkbench,等等 8- 操作流程: 9 - 1.安装扩展 10 - pip install flask_script 11 - pip install flask_migrate 12 - 2.导入三个类 13 - from flask_script import Manager 14 - from flask_migrate import Migrate, MigrateCommand 15 - 3.通过Manager类创建对象manager,管理app 16 - manager = Manager(app) 17 - 4.使用Migrate,关联db,app 18 - Migrate(app,db) 19 - 5.给manager添加一条操作命令 20 - manager.add_command("db",MigrateCommand) 21 - 相关迁移命令: 22 - 生成迁移文件夹 23 - python xxx.py db init 24 - 将模型类生成迁移脚本 25 - python xxx.py db migrate -m '注释' 26 - 将迁移脚本更新到数据库中 27 - python xxx.py db upgrade 28 29""" 30 31from flask import Flask 32from flask_script import Manager 33from flask_migrate import Migrate,MigrateCommand 34from flask_sqlalchemy import SQLAlchemy 35 36app = Flask(__name__) 37 38#设置数据库配置信息 39app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@localhost:3306/data39" 40app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False 41 42#创建SQLAlchemy对象,关联app 43db = SQLAlchemy(app) 44 45#3.通过Manager类创建对象manager,管理app 46manager = Manager(app) 47 48# 4.使用Migrate,关联db,app 49Migrate(app,db) 50 51# 5.给manager添加一条操作命令 52manager.add_command("db",MigrateCommand) 53 54# 6.编写模型类 55class Student(db.Model): 56 id = db.Column(db.Integer,primary_key=True) 57 name = db.Column(db.String(32)) 58 age = db.Column(db.Integer) 59 60 61@app.route('/') 62def hello_world(): 63 64 return "helloworld" 65 66if __name__ == '__main__': 67 manager.run()