数据库
# 任务概览
在前面插件的小节 封装了flask_sqlalchemy、flask_sqlalchemy.. 接下来, 我们要创建数据库表..
- 在orms目录下创建
__init__
文件, 把它变成一个包. 创建_base.py
文件, 在里面封装好一个基类 拥有创建和删除功能.. - 创建
department.py
文件, 创建部门表- 在orms包的
__init__
文件中引入创建好的部门表from .department import DepartmentORM
- 然后在pear_admin包的
__init__
中写入语句from pear_admin import orms
- 在orms包的
- 除了部门表, 同样的配方, 还得创建 角色表、用户表、权限表
- 表都创建好后, 迁移、生成表
- [step1] 启动mysql 在pycharm中连接mysql并且打开连接好的mysql的默认控制台 输入创建数据库的命令.
create database pear_admin character set utf8mb4;
- [step2] 在config.py中配置开发环境的数据库.
SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:admin1234@localhost:3306/pear_admin"
- [step3] 使用flask指令实现 pymysql的迁移!
pip install pymysql
flask db init
> 初始化迁移文件 会在项目根目录下自动生成目录migrations 注:记得手动在.gitignore
中添加排除!
flask db migrate
> 生成迁移记录.
flask db upgrade
> 根据迁移记录生成 - 若使用的是 SQLite 数据库, 迁移记录会在 instance 文件夹里..
- [step1] 启动mysql 在pycharm中连接mysql并且打开连接好的mysql的默认控制台 输入创建数据库的命令.
- 添加外键和添加关系, 多对多关系表的创建通过Table的形式实现
部门 自关联
;权限 自关联
;部门:用户 = 1:n
;用户:角色=n:n
;角色:权限=n:n
- 在orms目录下的
__init__
文件中 编写两张第三方表的代码. - 在用户表中添加多对多的关系 - 运用了backref,RoleORM角色表中就不用添加这个关系了.
- 在角色表中添加多对多的关系 - 运用了backref,RightsORM权限表中就不用添加这个关系了.
- 在orms目录下的
- 添加完后, 再进行一下迁移工作.. 会新增外键字段和两张第三方表.
- 最后, 用脚本读取csv文件, 添加测试数据..
- 我们通常会在
/static/data/
下放测试数据, 这里以csv格式存储..- 该项目应该有6张表, 按道理应该有6个csv文件, 但我们这里只有4个..
用户-角色 数据放在了用户表相关csv的rights_ids中; 角色-权限 数据放在了 角色csv的role_ids中 - csv文件里的字段比ORM表中的字段多, 没关系, 新增更新时, 不会用的字段插不进去的..
- 该项目应该有6张表, 按道理应该有6个csv文件, 但我们这里只有4个..
@app.cli.command()
-from .init_script import register_script
-register_script(app)
当我们在终端输入flask
命令, 可以看到多了个和@app.cli.command()
所装饰的函数同名的命令..
此处的命令叫做init, so, 我们在终端执行命令flask init
就会运行脚本..from flask import Flask, current_app
此处的current_app就是create_app函数返回的那个app!!
意味着 我可以在任一文件中 拿到config.py中配置的参数.. eg:root = current_app.config.get("ROOT_PATH")
SQLALCHEMY_ECHO = True
# 打印SQL语句, 在config.py中配置.- 运行脚本批量添加测试数据时, 可能会出现外键约束的错误, 不慌, 把约束暂时关掉就是..
from sqlalchemy import text
db.session.execute(text("SET FOREIGN_KEY_CHECKS = 0;")) # 关闭约束
db.session.execute(text("SET FOREIGN_KEY_CHECKS = 1;")) # 打开约束
- 我们通常会在
# 外键创建和关联关系示例
1:n 1对多
"""一个部门有多个用户 部门:用户=1:n"""
class DepartmentORM(BaseORM):
__tablename__ = "ums_department"
id = sa.Column(sa.Integer, primary_key=True, comment="部门ID")
# 关联关系 > 1的这方,反向 -- 部门对象.users 得到该部门的所有用户
users = relationship("UserORM")
class UserORM(BaseORM):
__tablename__ = "ums_user"
id = sa.Column(sa.Integer, primary_key=True, comment="自增id")
# 外键 1:n 写在多的这方
department_id = sa.Column(sa.Integer, db.ForeignKey('ums_department.id'),comment="部门id")
# 关联关系 > 多的这方,正向 -- back_populates指明反向的字段叫啥!! -- 用户对象.department 得到该用户所在部门
department = db.relationship('DepartmentORM', back_populates='users')
""" 利用backref简化关联关系的代码编写
class DepartmentORM(BaseORM):
__tablename__ = "ums_department"
id = sa.Column(sa.Integer, primary_key=True, comment="部门ID")
users = relationship("UserORM",backref='department')
class UserORM(BaseORM):
__tablename__ = "ums_user"
id = sa.Column(sa.Integer, primary_key=True, comment="自增id")
department_id = sa.Column(sa.Integer, db.ForeignKey('ums_department.id'),comment="部门id")
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
自关联
"""一个部门有多个子部门,子部门又有多个子部门 1:n的自关联"""
class DepartmentORM(BaseORM):
__tablename__ = "ums_department"
id = sa.Column(sa.Integer, primary_key=True, comment="部门ID")
# 外键 -- pid外键字段用于指向上级部门的id
pid = sa.Column(sa.Integer, sa.ForeignKey("ums_department.id"), default=1)
# 部门对象.parent -- 当前部门是子部门,将 所求部门/父部门 的id与 当前部门/子部门 的pid进行匹配! 值一个/直属父部门
parent = relationship("DepartmentORM", back_populates="children", remote_side=[id])
# 部门对象.children -- 当前部门是父部门,将 所求部门/子部门 的pid与 当前部门/父部门 的id进行匹配! 值多个
children = relationship("DepartmentORM", back_populates="parent", remote_side=[pid])
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
n:n 多对多
""" 一个用户可以有多个角色,一个角色可以有多个用户 n:n=用户:角色"""
user_role = sa.Table(
"ums_user_role", # 用户-角色中间表名称
db.metadata,
sa.Column("id", sa.Integer, primary_key=True, autoincrement=True, comment="标识"),
sa.Column("user_id", sa.Integer, sa.ForeignKey("ums_user.id"), comment="用户编号"),
sa.Column("role_id", sa.Integer, sa.ForeignKey("ums_role.id"), comment="角色编号"),
)
class UserORM(BaseORM):
__tablename__ = "ums_user"
id = sa.Column(sa.Integer, primary_key=True, comment="自增id")
# 关联关系 -- 用户对象.role_list 可以拿到该用户的所有角色
role_list = relationship(
"RoleORM",
secondary="ums_user_role",
back_populates='user_list'
)
class RoleORM(BaseORM):
__tablename__ = "ums_role"
id = sa.Column(sa.Integer, primary_key=True)
# 关联关系 -- 角色对象.user_list 可以拿到该角色的所有用户
user_list = relationship(
"UserORM",
secondary="ums_user_role",
back_populates='role_list'
)
""" 利用backref简化关联关系的代码编写
class UserORM(BaseORM):
__tablename__ = "ums_user"
id = sa.Column(sa.Integer, primary_key=True, comment="自增id")
# 关联关系
role_list = relationship(
"RoleORM",
secondary="ums_user_role",
backref=backref("user_list"),
lazy="dynamic",
)
class RoleORM(BaseORM):
__tablename__ = "ums_role"
id = sa.Column(sa.Integer, primary_key=True)
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49