current_app
'''current_app = LocalProxy(_find_app)request = LocalProxy(partial(_lookup_req_object, "request"))session = LocalProxy(partial(_lookup_req_object, "session"))g = LocalProxy(partial(_lookup_app_object, "g"))'''
代理的request这么一个类,在请求过程中
只要是访问路由,就可以通过current_app来获取到其他东西。
例如  current_app.config.
app同样可以获取到,为什么使用current_app.config?
是为了线程安全,通常一个app路由内只有一个请求。
current_app里面的属性是不会跑到别的app请求中去的,
但是在大型项目中,app逻辑代码并不是写在同一个模块下,在只想访问当前app路由的情况下使用current_app来调用,保证线程安全。
orm
什么是orm,关系映射,类似ssh中的数据层实现。
学习成本搞,但是性能比不上原生。
可以提高开发效率,应用元编程概念
sqlite
python自带sqlite3,小巧,且功能较为强大,百万计。
不需要联网,db信息保存在一个db格式的文件中,方便进行数据迁移。
多用于测试平台,单机小游戏。
编程模式上的区别
原生 sql ,谁都可以读懂,但是维护成本高,开发效率底
orm关系映射对象,层层封装,将简单的sql查询进行封装,
通过类,属性,方法的方式映射sql语句进行调用
好处
避免sql注入,各个不同的数据需要不同的查询sql,这个不用
坏处
每一个具体的语法是不一样的,sql语句大体通用,学习成本高。
使用流程
导包
from flask_sqlalchemy import SQLAlchemyfrom flask_migrate import Migratefrom flask import Flask# 初始化 db 数据库对象,吧app和db绑定到一起app = Flask(__name__)app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@localhost:3306/demo"app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = Falsedb uri地址构成mysql(db类型),pymysql(引擎)://root(用户名):密码@localhost:3306/demo(db name)使用sqlite 3个斜杠,linux下是 4个斜杠# --------- 一个项目使用多个数据库的情况下 ,绑定多个dbapp.config['SQLALCHEMY_BINDS']={'users':"sqlite:///d:/demo1.db"}模型类也要绑定class user(db.Model):__bind_key__ ="user"app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = Falsedb = SQLAlchemy(app)
绑定与延迟绑定
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@localhost:3306/demo"app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = Falsedb = SQLAlchemy(app)延迟绑定db.init_app(app) # 初始化db绑定app,但是一定要再app路由生效之前,要注意代码执行顺序
编写数据库表类并构建DB
class User(db.Model):__tablename__ = "user"id = db.Column(db.Integer, primary_key=True)username = db.Column(db.String(80), unique=True)email = db.Column(db.String(120), unique=True)## 通过migrate 构建数据库# 1,迁移的时候更加方便# 2,可以动态修改db结构migrate = Migrate(app, db)
migrate 方式常用命令
初始化 flask db init
该命令会新建一个名字位migrations的文件夹,并记录一个数据库版本号
一份保留再migrations中,一份保存再数据库中(新建一张名字为alembic_version的表来保存
值得注意的是新建了migrations文件夹后需要对db模型进行修改,然后使用flask-migrations进行迁移,
这样才产生第一个版本号。
数据迁移 flask db migrate
升级 flask db upgrade
每次db模型变化,需要重复使用migrate命令和upgrade命令,
按照顺序组合使用,成功后会修改版本号。
帮助
数据模型定义参数说明
class User(db.Model):__tablename__="user"id = db.Column(db.Integer,primary_key=True)username = db.Column(db.String(80),unique=True)email = db.Column(db.String(120),unique=True)属性db.Model 继承db下面的基类,与db进行绑定db.Column最常的数据格式db.String 字符串需要指明长度db.Text 长的unicode文本DateTime 表示为python datetime 对象的时间和日企intgersmallintgerfloatBoolean 存储布尔值PickleType 存储为一个持久化的python对象LargeBinary 存储一个任意大的二进制数据参数db.ForeginKey('project.id')primary.key 主键,唯一标示autoincrement 自增长unique 唯一index 索引可以极大的提高查询的速度,但是索引很多的话,查询速度会降低,且写入速度会降低nullable 不为空default 默认comment 说明,注释
简单操作
@app.route("/")def index():new_user = User(username="addicated",email="demo")db.session.add(new_user)db.session.commit()return "hello"# 查询@app.route("/")def index():users = User.query.all()print(users)return "hello"user =User(username="demo")db.session.add(user)# 添加多个# db.session.add_all([user1,user2])
事务
与各种db处理逻辑一样,orm同样支持事务操作
# 事务,一连串的数据库操作、# 加一个异常处理,如果报错了就rollbacktry:db.session.commit() # 只有在commit的时候才会生效到数据库中except:db.session.rollback()
Query对象
# orm# 1,所有的all() 查询满足条件的所有字段# users= User.query.where().group_by().offset().all() # 支持链式调用users = User.query.all()# 基本原理是每个方法都返回一个统一的方法,之后就可以一直调用下去# 直到返回的不再是同一个对象或者方法# 2,first 拿到查询的第一个结果user = User.query.first()# 3,get方法 要通过主键去获取 主键唯一,是一个位置参数user = User.query.get(5) # 位置传参,不能# 表内有多个主键的情况下,使用元祖传入进去# 或者使用字典 kv方式传入进去# 如果没获取到,会返回一个None,获取到的话会返回一个模型# 如果没返回数据,想要其报错的话,Query.get_or_404()# 4,filter_by()# 第一种 使用filter_by方法Query.filter_by()# 5 filter() 进行更为复杂的查询Query.filter() # 位置传参User.query.filter(User.email.endswith("xxx")).all()# 支持字段很多,在ColumnOperators中进行确认ColumnOperators# 6 按照某种规则对用户进行排序User.query.order_by(User.username.desc().all())# 7 限制返回用户的数量,应用场景,进行分页User.query.order_by(User.username.desc()).limit(1).all()# 删除db.session.delete("")# 删除需要commit才能生效# first_or_404# 没有找到就abort() 和异常处理机制配合起来使用# 数据更新user = User()db.session.add(user)# 添加多个# db.session.add_all([user1,user2])db.session.ccommit()# orm 执行原生sql语句users = db.session.execute("select * from users")# 原生sql语句的参数化sql = "select * from user where name=:name"a = db.session.execute(sql, params={'name': "value"})print(a.fetchall())
