跳转至

Flask入门笔记-19_SQLAlchemy自定义上下文

SQLAlchemy对象绑定到应用

  • 使用FLASK_APP对象创建一个SQLAlchemy的连接对象,这个连接对象就只能操作这个FLASK_APP
  • 如果只使用一个APP,只需要把使用SQLAlchemy 创建一个对象,把FLASK_APP传给 SQLAlchemy 构造方法来创建一个SQLAlchemy的对象
  • Flask 视图函数中自动配置一个应用上下文
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import func
from sqlalchemy.orm import load_only
# 创建应用
app = Flask(__name__)

# 配置数据库的链接地址
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:2233@127.0.0.1:3306/test1'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_ECHO'] = True

# 创建SQLAlchemy绑定APP的对象,把FLASK_APP传给 SQLAlchemy 构造方法
db_cli = SQLAlchemy(app)

@app.route('/')
def index():
    # 在视图中工作的SQLAlchemy对象已经在上下文环境中了,所以可以直接使用
    data = db_cli.session.query(User.name, User.email).all()
    print(data)
    return 'This is index'

动态配置应用上下文

  • 使用SQLAlchemy的init_app方法(传入一个Flask_app)来创建一个全新的app,我们使用这个app来管理视图
  • 要使用不止一个应用或者在一个函数中动态地创建应用的话需要使用配置应用上下文
  • 实例化SQLAlchemy对象时,不必传入FLASK对象进行绑定,而是在APP创建好后,我们使用SQLAlchemy的init_app方法来重新生成一个 app 对象,这个应用内开启了SQLAlchemy上下文环境
# 摘自官方文档

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

db = SQLAlchemy()

def create_app():
    app = Flask(__name__)
    db.init_app(app)
    return app

Demo

  • 比如我们在定时任务中,可能希望服务器运行时,就执行一段代码,我们把一段 独立的函数 写到了和 app 同级, 但是函数体内却需要使用 app 的数据库连接配置
  • 这时候就需要我们手动开启应用的上下文了
 # 创建 SQLAlchemy 对象
db = SQLAlchemy()

# Flask对象在创建好后,直接使用SQLAlchemy对象的init_app创建app
app = db.init_app(Flask(__name__))

# 创建视图
@app.route('/')
def index():
    # 如下: 在视图中直接使用SQLAlchemy对象直接对数据库操作,
    db.session.query(User.age, func.count(User.name)).group_by(User.age).all()
    return 'This is index'



# 自定义一个 独立函数体 (如果想使用SQLAlchemy对象操作数据库需要传入把app当错参数传入)
def test(Flask_app):
    # 开启外部传进来的 app 对象
    with app.app_context():
        db.session.query(User.age,func.count(User.name)).group_by(User.age).all()

# 创建执行器
executor = ThreadPoolExecutor()
# 设置调度器(动态的给类绑定一个方法)
app.scheduler = BackgroundScheduler({'defaule': executor})
# 添加任务(立即执行)
app.scheduler.add_job(test, 'date', args=[app])
#开启任务
app.scheduler.start()