#使用Migrate的步骤:
#1. import flask_migrate包
#2. 调用Migrate方法:Migrate(app,db)参数分别是Flask对象和SQLAlchemy对象
#3. 定义环境变量(Windows/Linux):set/export FLASK_APP=ModelClass.py 这个脚本是定义模型类的脚本路径,一般在当前目录下定义。
#4. 在命令行执行命令: flask db init 该命令创建归并目录,执行一次即可,在执行中会import FLASK_APP指定的脚本,为避免一级代码在import中被执行导致的异常,可以放到if __name__块中。
#5. 在命令行执行命令: flask db migrate -m "执行返回的信息" 改命令创建归并文件
#6. 在命令行执行命令: flask db upgrade 该命令实际把更新提交到数据库。
import os
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask import Flask,render_template,url_for,redirect,flash,request
f_instance=Flask(__name__)
f_instance.config['SECRET_KEY']='flasksecret'
basedir=os.path.dirname(os.path.abspath(__file__))
# Connects our Flask App to our Database
f_instance.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
f_instance.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(f_instance)
class Approvement(db.Model):
__tablename__='approvements'
id=db.Column(db.Integer,primary_key=True)
result=db.Column(db.Text)
app_id=db.Column(db.Integer)
app_note=db.Column(db.Text)
def __init__(self,result,app_id):
self.id = id #这里如果不定义self.id,在以后查询结果对象中无法访问id属性。但如果这里指定了id私有属性,在向表中添加纪录时id字段必须要赋值。
self.result=result
self.app_id=app_id
self.app_note="Default"
class Application(db.Model):
__tablename__='applications'
id=db.Column(db.Integer,primary_key=True)
note=db.Column(db.Text)
def __init__(self,note):
#self.id = id #这里不定义id属性,在向表中添加纪录时,由于类中定义了id字段为主键,SQLAlchemy会为id赋值一个自增值,但查询结果中无法访问id属性。
self.note=note
if __name__=="__main__":
#db.create_all() #如果不用Migrate,可以直接在指定路径上创建数据库(一个文件)并根据本python文件模型类的定义在数据库中创建表,每个模型类对应一个表。
#db.create_all() 不用Migrate的话可以用来创建上面所有model类定义的表。但是不能重复执行,所以Migrate更方便一些,
apl1=Application('my first application')
apl2=Application('my second application')
apv1=Approvement('approvement for apl1',1)
apv1.id=1
apv2=Approvement('approvement for apl2',2)
apv2.id=2
#db.session.add(apl1)添加一条记录,会根据记录的对象类型自动确定添加到哪个表中。
db.session.add_all([apl1,apl2,apv1,apv2]) #可以同时添加不同表的记录
db.session.add_all([apl1,apl2,apv1,apv2]) #重复执行会把旧纪录覆盖掉。通过这个特性实现更新操作:先检索出需要修改的记录,然后按要求更新对象属性,最后add到数据库替换旧纪录。
db.session.commit
#查询表中的内容可以通过模型类的方法:
apl=Application.query.get(1)
print(f"get record:{apl.id}-{apl.note}") #因为apl.id访问无效,返回异常。
apls=Application.query.all() #返回一个列表
print(f"all records:{len(apls)}")
apvs=Approvement.query.filter_by(id=1).all()
print(f"filter records:{apvs}")
#如果只执行数据库的操作不需要启动Flask Web 应用。
#f_instance.run(debug=True)
else:
#Migrate放到这里,避免直接执行当前脚本时被调用。因为我们只希望当前脚本被flask db init命令import时调用Migrate。
Migrate(f_instance,db) #Migrate用来归并当前python文件中对数据库的表结构变更和数据增删。