flask-sqlalchemy + flask-migrate orm迁移数据库

一、flask-sqlalchemy 数据库操控模型

1、基础用法增删改查

(1)建立模型文件,learn_sql.py(名字可以随便起),直接运行改文件可在数据库中创建下student表

from flask_sqlalchemy import SQLAlchemy
from flask import Flask

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:[email protected]:3306/test?charset=utf8"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["SECRET_KEY"] = "FKAJDSHKJ"

# 实例化db
db = SQLAlchemy(app)

# 学生表
class Student(db.Model):
    __tablename__ = "student"
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(64), nullable = False)
    gender = db.Column(db.Enum("男", "女"), nullable = False)
    phone = db.Column(db.String(11))
    class_name = db.Column(db.String(200), nullable = False)

if __name__ == "__main__":
    db.create_all()
    #删除所有数据库
    # db.drop_all()

(2)单表增查改删,创建operate_new_sql.py(文件名随便起)

(2.1)增加一条数据

from learn_sql import db, Student

s = Student(name = "dlrb", gender = "女", phone = "13677889078")
s1 = Student(name = "mrzh", gender = "男", phone = "13677889078")
s2 = Student(name = "lufei", gender = "男", phone = "13677889078")
s3 = Student(name = "dijia", gender = "女", phone = "13677889078")

# 添加一条数据
db.session.add(s)
# 添加多条数据
db.session.add_all([s1, s2, s3])

# 提交
db.session.commit()

(2.2) 查数据

 使用filter进行条件查询的时候,可以不使用all(),但是如果有多个满足条件,那会返回一个迭代器,可以进行遍历.

from learn_sql import db, Student

# get查询
# get里面的参数是和表里面id进行匹配,返回一个对象
stu = Student.query.get(2)
print(stu.name) # 打印出id=2,name字段的数据

# 查全部
stu = Student.query.all() # 返回列表,元素是对象
print(stu)

# 条件查询 filter()
stu = Student.query.filter(Student.id > 5).all()
print(stu)

# 条件查询filter_by(id > 5)[不可行],, 不能进行范围查询
# 使用多个filter_by 或者 filter,可以多条件判断
stu = Student.query.filter_by(gender='男').filter_by(name='张三2').all()
print(stu)

# 模糊查询
stu = Student.query.filter(Student.name.like('%张%')).all()
print(stu)

(2.3) 修改数据

from learn_sql import db, Student


# 第一种改,update
stu = Student.query.filter_by(id = 3).update({"name":"历史"})
db.session.commit()

# 也可以全部改
stu = Student.query.filter(Student.name=='张三').update({"gender":"女"})
db.session.commit()

# 第二种
stu = Student.query.filter(Student.gender=='女')[0]
stu.name = 'lyf'
db.session.commit()

(2.4) 删除数据

from learn_sql import db, Student

stu = Student.query.filter_by(gender='男')
db.session.delete(stu)
db.session.commit()

2、多表关系(1对N, N对M)

(1) 1对多, 在learn_sql.py文件中,建立新的模型,成绩表

  1. 每个学生都有多个成绩,所有在成绩表中设立外键,成绩表的student_id参照student表的id
  2. 设立关联字段,原则是: 在1的一方设立关联
from flask_sqlalchemy import SQLAlchemy
from flask import Flask

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:[email protected]:3306/test?charset=utf8"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["SECRET_KEY"] = "FKAJDSHKJ"

# 实例化db
db = SQLAlchemy(app)

# 学生表
class Student(db.Model):
    __tablename__ = "student"
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(64), nullable = False)
    gender = db.Column(db.Enum("男", "女"), nullable = False)
    phone = db.Column(db.String(11))
    class_name = db.Column(db.String(200), nullable = False)
    # 关联
    # 含义介绍:
    # 学生表和成绩表为: 1:N,所以在1中进行关联N,,
    # grades字段为关联字段,可以通过grades进行访问成绩表中的字段内容,
    # backref字段为反向访问,在成绩表中可以,通过student字段进行访问Student表的所有字段内容
    grades = db.relationship("Grade", backref="student")

# 成绩表
# 学生表:成绩表 = 1:N
class Grade(db.Model):
    __tablename__ = "grade"
    id = db.Column(db.Integer, primary_key = True)
    course_id = db.Column(db.Integer, primary_key = True)
    grade = db.Column(db.String(3), nullable = False)
    student_id = db.Column(db.Integer, db.ForeignKey("student.id"), nullable = False) # 添加外键

if __name__ == "__main__":
    db.create_all()
    #删除所有数据库
    # db.drop_all()

(1.1) 应用

from learn_sql import db, Student, Grade

# 1 访问多
stu = Student.query.get(2)
for i in stu.grades:
    print(stu.name, i.grade)

# student表中查询到id=2的数据,通过grades字段可以查到,该学生有多门成绩


# N 访问1
grade = Grade.query.get(4)
print(grade.grade, grade.student.name)

# grade表中查询id=4的数据,通过反向student字段,可以知道成绩id=4,是哪位学生的成绩

(2) 多对多,多对多得借助第三方表

 比如学生和课程,学生可以选择多门课程,一门课程可以有多名学生

  1. 多对多的模型建立,必须要借助第三方表
  2. 其中student和course在查询的时候,用student表进行查询,可以使用courses字段查看到学生选择了哪些课程; 用course表进行查询的时候, 可以使用反向字段student进行查看本门课程有哪些学生进行选择
  3. 第三方表只用作联系两表, 不能通过第三表的字段查询到学生的姓名, 或者课程名称的操作
from flask_sqlalchemy import SQLAlchemy
from flask import Flask

from flask_sqlalchemy import SQLAlchemy
from flask import Flask

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:[email protected]:3306/test?charset=utf8"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["SECRET_KEY"] = "FKAJDSHKJ"

# 实例化db
db = SQLAlchemy(app)

# 学生表
class Student(db.Model):
    __tablename__ = "student"
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(64), nullable = False)
    gender = db.Column(db.Enum("男", "女"), nullable = False)
    phone = db.Column(db.String(11))
    class_name = db.Column(db.String(200), nullable = False)
    # N:M
    courses = db.relationship("Course", secondary="student_to_course", backref="student")

# 第三张表,选课表,,学生表:课程表 = n:m
class StudentToCourse(db.Model):
    __tablename__ = "student_to_course"
    id = db.Column(db.Integer, primary_key = True)
    student_id = db.Column(db.Integer, db.ForeignKey("student.id"), nullable = False) # 添加外键, 学生表id
    course_id = db.Column(db.Integer, db.ForeignKey("course.id"), nullable = False) # 添加外键,,课程表id

# 课程表
class Course(db.Model):
    __tablename__ = "course"
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(64), nullable = False)

if __name__ == "__main__":
    db.create_all()
    #删除所有数据库
    # db.drop_all()

  (2.1) 应用

from learn_sql import db, Student, Course

# N访问M,通过学生,找到学生选择的课程名
student = Student.query.get(1)
print(student.courses[0].name)

# M访问N, 通过课程,找到选择该课程的学生姓名
course = Course.query.get(1)
print(course.student[0].name)

二、flask-migrate orm迁移数据库

flask-sqlalchemy为我们提供了很方便的数据库管理,但是也是不足,其中如果我突然发现表不合适了,我想增加一个字段,或者改变字段的长度,原始的方法,只能删除所有表再重新创建,这可以明显感觉到很不合理,如果我已经有数据了呢,那不就会造成数据丢失吗.所有这里引入了flask-migrate进行数据库的迁移.

使用步骤:

(1) 在app.py (必须要有app文件) 文件进行引入app和db两个对象,然后再实例化一个migrate对象

from learn_sql import app, db
from flask_migrate import Migrate

migrate = Migrate(app, db)

(2) 在终端进入对象的目录下------>flask db init -------->初始化迁移

(3) flask db migrate -m '内容说明' --------> 创建迁移文件 (会出现migrations目录)

(4) flask db upgrade -------> 更新数据库

(5) 默认情况下,字段的长度,字段的类型发生改变的时候,不会进行比较修改,在migrations目录下修改env.py文件,搜索run_migrations_online函数,加入以下配置:

context.configure(
            ......
            compare_type=True,  # 检查字段类型
            compare_server_default=True, # 比较默认值
            ......
        )

推荐一个写的较全的博客园: Flask 模型操作 - 羊驼之歌 - 博客园

你可能感兴趣的:(python,flask,数据库,python)