• 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() 也会自动保存了。

  • 相关阅读:
    设计模式研究
    requests模块请求常用参数的写法整理
    python程序打包exe文件
    爬虫响应信息乱码解决方式
    Vue-cli父子组件之间传参
    MYSQL事件隔离级别以及复读,幻读,脏读的理解
    [NOIP2009] 提高组 洛谷P1073 最优贸易
    [NOIP2009] 提高组 洛谷P1071 潜伏者
    [NOIP2009] 普及组
    洛谷P3386 【模板】二分图匹配
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/16629630.html
Copyright © 2020-2023  润新知