Flask-SQLAlchemy插件
这个插件是在SQLAlchemy的基础上再进行封装,使之在Flask框架内使用更加方便
安装方式
pip install Flask-SQLAlchemy
使用方法
- 导入Flask、Flask-SQLAlchemy
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
- 配置数据库, 配置方法与之前是一样的 (这部分内容后面可以写入配置文件)
# 数据库配置
HOSTNAME = "localhost"
DATANAME = "demo0427"
PORT = 3306
USERNAME = "root"
PASSOWRD = "root"
DB_URL = "mysql+mysqlconnector://{}:{}@{}:{}/{}?charset=utf8".format(USERNAME, PASSOWRD, HOSTNAME, PORT, DATANAME)
- 实例化Flask类, 配置config
app = Flask(__name__)
# config配置项
app.config["SQLALCHEMY_DATABASE_URI"] = DB_URL # 写入数据库配置
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
- 创建数据库引擎
# 创建数据库引擎
db = SQLAlchemy(app)
- 定义模型类
- 这里不需要再导入Column、Integer等创建表需要的类了, 只需要db.Column、db.Integer即可
- 表约束的使用方式与之前一样
- 外键(ForeignKey)和表关联(relationship)的方式也一样
- 补充说明,模型类中如果不写__tablename__ ,那么将以模型类的名字的小写作为表名
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(50))
class Artcile(db.Model):
# 如果不写__tablename__,会以模型类的名字的小写作为表名
__tablename__ = "article"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(50))
uid = db.Column(db.Integer, db.ForeignKey("users.id")) # 外键
author = db.relationship("User", backref="articles") # 表关联
db.drop_all() # 删除数据库
db.create_all() # 创建数据库
- 设置路由
@app.route("/")
def index():
return "首页"
if __name__ == '__main__':
app.run(debug=True)
添加数据
# 添加数据
user = User(name="connor")
article = Artcile(title="python")
article.author = user
db.session.add(article)
db.session.commit()
查询数据
# 查询数据
user = User.query.all()
print(user)
# 排序
artcile = Artcile.query.order_by(Artcile.id.desc()).all()
print(artcile)
# 原来的查询方式其实一样可以使用
artcile = db.session.query(Artcile).all()
print(artcile)
删除数据
article = Artcile.query.first()
db.session.delete(article)
db.session.commit()
更新数据
# 更新数据
artcile = Artcile.query.filter(Artcile.title == "java").first()
artcile.title = "python"
db.session.commit()
Flask-Script
Flask-Script的作用是可以通过命令行的形式来操作Flask。例如通过命令跑一个开发版本的服务器、设置数据库,定时任务等。
安装方式
pip install flask-script
使用方法
之前的代码中,数据库的配置以及模型类都写在了视图文件中,但真实工作中这是不可取的。其实可以创建一个manage.py文件,然后通过命令行执行数据库的映射操作。
做一个小功能,用命令行添加管理员账号
- 创建新的项目目录,然后创建flask_admin.py、config.py文件
在config文件中写入
# 数据库配置
HOSTNAME = "localhost"
DATANAME = "demo0427"
PORT = 3306
USERNAME = "root"
PASSOWRD = "root"
DB_URL = "mysql+mysqlconnector://{}:{}@{}:{}/{}?charset=utf8".format(USERNAME, PASSOWRD, HOSTNAME, PORT, DATANAME)
SQLALCHEMY_DATABASE_URI = DB_URL # 写入数据库配置
SQLALCHEMY_TRACK_MODIFICATIONS = False
在flask_admin.py文件中导入并加载config,然后定义模型类
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import config
app = Flask(__name__)
app.config.from_object(config)
db = SQLAlchemy(app)
class AdminUser(db.Model):
__tablename__ = "admin_users"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(50))
email = db.Column(db.String(50))
db.create_all()
if __name__ == '__main__':
app.run(debug=True)
- 创建manage.py文件
- 需要导入Manager模块,并且导入flask_admin里面的app、AdminUser、db
from flask_script import Manager
from flask_admin import app, AdminUser, db
# 实例化manager类
manage = Manager(app)
# 设置参数并定义添加用户的方法
@manage.option('-n', '--name', dest='name')
@manage.option('-e', '--email', dest='email')
def add_user(name, email):
user = AdminUser(name=name, email=email)
db.session.add(user)
db.session.commit()
- 在命令行输入python manage.py add_user -n connor2 -e 123@qq.com
添加成功
Flask-Migrate
在实际的开发环境中,经常会发生数据库修改的行为。一般我们修改数据库不会直接手动的去修改,而是去修改ORM对应的模型,然后再把模型映射到数据库中。这时候如果有一个工具能专门做这种事情,就显得非常有用了,而flask-migrate就是做这个事情的。flask-migrate是基于Alembic进行的一个封装,并集成到Flask中,而所有的迁移操作其实都是Alembic做的,他能跟踪模型的变化,并将变化映射到数据库中。
安装方式
pip install flask-migrate
使用方式
做一个小项目
- 1.创建一个新的项目目录
- 创建flask_app.py文件, 程序的主入口
- 创建config.py文件, 配置项文件
- 创建models, 模型类文件
- 在flask_app.py文件写入
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import config
from models import User
app = Flask(__name__)
app.config.from_object(config) # 加载配置文件
db = SQLAlchemy(app) # 加载模型类
@app.route("/")
def index():
return "首页 "
if __name__ == '__main__':
app.run(debug=True)
- 在config.py文件中写入
# 数据库配置
HOSTNAME = "localhost"
DATANAME = "demo0427"
PORT = 3306
USERNAME = "root"
PASSOWRD = "root"
DB_URL = "mysql+mysqlconnector://{}:{}@{}:{}/{}?charset=utf8".format(USERNAME, PASSOWRD, HOSTNAME, PORT, DATANAME)
SQLALCHEMY_DATABASE_URI = DB_URL # 写入数据库配置
SQLALCHEMY_TRACK_MODIFICATIONS = False
- 在models.py文件中写入
from flask_app import db
class User(db.Model):
__tablename__ = "project_users"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(50))
email = db.Column(db.String(50))
password = db.Column(db.String(50))
理论上是这样做的, 但这样做实际上有BUG, 因为flask_app和models互相导入了,此时运行主文件会抛出异常.
要解决这个问题只需要再创建一个文件, 让flask_app和models导入它就可以解决这种互相导入的问题了.
创建一个etxs.py文件并写入
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
由于这个文件已经实例化了SQLAlchemy类了, 因此flask_app文件就不需要在实例化它了, 因此修改flask_app代码
from etxs import db # 增加导入etxs文件
# db = SQLAlchemy(app) # 注释这段代码
db.init_app(app) # 新增这段代码, 用于加载模型类
然后修改models.py文件, 不在从flask_app.py文件导入db, 而是从etxs.py文件导入db
# from flask_app import db # 注释
from etxs import db # 导入etxs的db
做完上面的操作之后, 还需要再创建一个manage.py文件, 要通过这个文件去映射数据库
# 通过这个文件映射数据库
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from etxs import db
from flask_app import app
# 映射哪个模型就导入哪个
from models import User
manage = Manager(app)
Migrate(app, db)
manage.add_command("db", MigrateCommand)
if __name__ == '__main__':
manage.run()
接着就可以通过命令行映射数据库了
# 1. 初始化
python manage.py db init
# 2. 将模型类迁移到文件中
python manage.py db migrate
# 3. 映射到数据库中
python manage.py db upgrade
如果此时修改模型类,比如增加一个字段
from etxs import db
class User(db.Model):
__tablename__ = "project_users"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(50))
email = db.Column(db.String(50))
password = db.Column(db.String(50))
age = db.Column(db.Integer) # 增加年龄字段
此时只需要在命令行中再次执行下面两个步骤即可,后续的每一次对模型类做更改都是通过这种方式实现。
# 2. 将模型类迁移到文件中
python manage.py db migrate
# 3. 映射到数据库中
python manage.py db upgrade