Flask 学习-19.配置管理flask_sqlalchemy 和 flask_migrate

前言

前面讲了项目中使用config.py 可以管理开发、生产、测试等环境的配置,这篇继续学习在项目中添加flask_sqlalchemy 和 flask_migrate 的配置

环境准备

先pip安装flask_sqlalchemy 和 flask_migrate

pip install flask_sqlalchemy
pip install flask_migrate

flask_sqlalchemy是封装了sqlalchemy 实现 ORM 操作数据库,flask_migrate 模块可以实现数据迁移和同步。

create_app() 工厂函数

flask_sqlalchemy 注册到app中有2种方法
方法一:直接在初始化的时候传app参数

# 初始化组件对象, 直接关联Flask应用
db = SQLAlchemy(app)

方法二:使用db.init_app(app)方法

# 先实例化,后关联app
db = SQLAlchemy()
# 初始化db,关联flask 项目
db.app = app    # 这一步需先设置属性,很多老的教程都缺少这一步,导致连不上数据库
db.init_app(app)

我们需要在 create_app() 工厂函数中初始化db实例,但是后面数据库操作会用到db对象,所以db对象就不能写对函数内部(函数内部是局部变量)

db = SQLAlchemy() 实例化数据库操作写到函数外部

from flask import Flask
import os
from flask_sqlalchemy import SQLAlchemy
from config import config_env
from flask_migrate import Migrate


db = SQLAlchemy()          # 数据库


def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__, instance_relative_config=True)
    # 从环境配置文件获取当前环境, 没有就拿缺省值"production"
    env = os.getenv("FLASK_ENV") or "production"
    print(f'当前运行环境:{env}')
    app.config.from_object(config_env.get(env))  # 获取相应的配置类
    # db 数据库初始化
    db.init_app(app)
    # migrate 迁移组件初始化
    Migrate(app, db)

    # app.config.from_mapping(
    #     SECRET_KEY='dev',
    #     DATABASE=os.path.join(app.instance_path, 'apps.sqlite'),
    # )
    #
    # if test_config is None:
    #     # load the instance config, if it exists, when not testing
    #     app.config.from_pyfile('config.py', silent=True)
    # else:
    #     # load the test config if passed in
    #     app.config.from_mapping(test_config)
    #
    # ensure the instance folder exists
    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass

    # 注册蓝图
    from . import auth
    from . import blog
    app.register_blueprint(auth.bp)
    app.register_blueprint(blog.bp)
    return app

配置不同环境

在config.py 中配置不同环境对象,继承一个基础的Config类

import os


class Config(object):
    # DEBUG = False
    JSON_AS_ASCII = False
    # 设置SECRET_KEY
    SECRET_KEY = os.urandom(24)  # 随机字符串


class DevelopmentConfig(Config):
    """开发环境"""
    DEBUG = True
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:123456@127.0.0.1:3306/web'
    # 是否追踪数据库修改,一般不开启, 会影响性能
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    # 是否显示底层执行的SQL语句
    SQLALCHEMY_ECHO = True


class ProductionConfig(Config):
    """生产环境"""
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:123456@x.x.x.x:3306/web'
    # 是否追踪数据库修改,一般不开启, 会影响性能
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    # 是否显示底层执行的SQL语句
    SQLALCHEMY_ECHO = False


class TestingConfig(Config):
    """测试环境"""
    TESTING = True


# 映射环境对象
config_env = {
    'development': DevelopmentConfig,
    'production': ProductionConfig,
    'testing': TestingConfig
}

模型

在apps.py文件创建一个models.py 模型文件,专门管理数据库模型

from . import db


# 创建模型
class Students(db.Model):
    __tablename__ = 'students'  # 数据库表名

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(20))
    fullname = db.Column(db.String(30))
    nickname = db.Column(db.String(30))

    def __repr__(self):
        return "<Students(name='%s', fullname='%s', nickname='%s')>" % (
                 self.name, self.fullname, self.nickname)


class Users(db.Model):
    __tablename__ = 'user'  # 数据库表名

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(30))

    def __repr__(self):
        return f"<Users(id='{self.id}', name='{self.name}')>"

同步数据库

执行数据库迁移命令

flask db init  # 生成迁移文件夹  只执行一次
flask db migrate  # ⽣成迁移版本, 保存到迁移文件夹中
flask db upgrade  # 执行迁移

于是可以看到生成了对应的表

测试添加数据

在app.py 的hello视图函数中测试添加数据到数据库

from apps import create_app, db
from apps import models


app = create_app()


@app.route('/hello')
def hello():
    # 数据库交互
    # 实例化 Students 模型对象
    user = models.Students(name='yy', fullname='yoyo')
    # 添加到会话,并用commit提交数据
    db.session.add(user)
    db.session.commit()
    return {"code": "0", "msg": "添加成功"}


if __name__ == '__main__':
    app.run()

启动服务后,访问http://127.0.0.1:5000/hello

查看数据库students表,数据添加成功

自动提交commit()

除了查询操作,其它添加数据修改数据,都需要加上 db.session.commit() 才会生效,很多小伙伴容易忘记这个操作,在配置里面可以加一个配置项

    # 不需要commit 自动保存, 默认False
    SQLALCHEMY_COMMIT_ON_TEARDOWN = True

这样不用 db.session.commit() 也会自动保存了。

posted @ 2022-08-26 23:58  上海-悠悠  阅读(1160)  评论(1编辑  收藏  举报