前言
前面讲了项目中使用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)
# 从环境配置文件获取当前环境, 没有就拿缺省值"development"
env = os.getenv("FLASK_ENV") or "development"
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:[email protected]:3306/web'
# 是否追踪数据库修改,一般不开启, 会影响性能
SQLALCHEMY_TRACK_MODIFICATIONS = False
# 是否显示底层执行的SQL语句
SQLALCHEMY_ECHO = True
class ProductionConfig(Config):
"""生产环境"""
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:[email protected]: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()
也会自动保存了。