Skip to content

生成数据库

迁移数据库之前。需要再 app 创建的目录导入才能在做数据库迁移的时候检测到之间封装好的模型。

python
from pear_admin.orms import UserORM

如果使用的是 MySQL 需要先创建数据库之后才能进行迁移。

sql
create database pear_admin character set 'utf8mb4';

注意

MySQL 数据库执行迁移之前请检查配置文件中的 SQLALCHEMY_DATABASE_URI 是否正确。

如果使用 SQLite 作为测试数据库,直接迁移即可。

因为之前项目的包目录更改为了 pear_admin,记得修改一下 .flaskenv 的配置文件。

shell
FLASK_DEBUG=True                # 开启调试模式
FLASK_RUN_PORT=5050			    # 设置运行的端口
FLASK_RUN_HOST=0.0.0.0		    # 设置监听的 ip
FLASK_APP="apps:create_app()"   # 运行程序
FLASK_APP="pear_admin:create_app()"   # 运行程序

执行迁移命令

初始化迁移文件

shell
flask db init

生成迁移脚本

shell
flask db migrate

将迁移脚本执行升级

shell
flask db upgrade

因为我使用的是 SQLite 数据库,在当前项目的 instance 目录下就会生成一个 pear_admin.db 的文件,里面存放了对应的数据表结构。如果是 MySQL 数据库,也可以在数据库中看到生成的表。

注意

项目中为什么不使用 MySQL 而选择 SQLite 作为开发使用?

实际上二者选择任意一个均可。实际我在做项目的时候也是使用 MySQL,但是开发时 MySQL 配置起来比 SQLite 稍微繁琐,如果想使用 MySQL 作为开发数据库,修改一下配置文件中的 SQLALCHEMY_DATABASE_URI 即可。

提交之前,记得把一些不需要的文件添加到 .gitignore

.idea/
.venv/
*.py[cod]
instance/
migrations/

添加测试数据

在开发的过程中会需要一些测试数据,这里使用脚本自动生成。在 /static/data/ 目录下准备以下数据。

id,name,leader,enable,pid
1,集团总部,集团负责人,,0
2,济南分公司,就眠仪式,,1
3,唐山分公司,mkg,,1
4,济南分公司-开发部,就眠仪式,,2
5,唐山分公司-测试部,mkg,,3
6,长沙某公司,正心全栈编程,,0
7,长沙某公司-VIP服务中心,正心全栈编程,,6
8,长沙某公司-招生中心,正心全栈编程,,6
9,长沙某公司-运营中心,正心全栈编程,,6
id,name,code,type,url,icon_sign,status,sort,open_type,pid
100,系统管理,ums:rights,menu,,layui-icon layui-icon-set-fill,,2,,0
101,权限管理,ums:rights:list,path,/system/rights.html,layui-icon layui-icon-console,,2,,100
102,新增权限,ums:rights:create,auth,,,,0,,101
103,修改权限,ums:rights:update,auth,,,,0,,101
104,获取权限,ums:rights:read,auth,,,,0,,101
105,删除权限,ums:rights:delete,auth,,,,0,,101
106,角色管理,ums:role,path,/system/role.html,layui-icon layui-icon-console,,3,,100
107,新增角色,ums:role:create,auth,,,,0,,106
109,修改角色,ums:role:update,auth,,,,0,,106
108,查询角色,ums:role:read,auth,,,,0,,106
110,删除角色,ums:role:delete,auth,,,,0,,106
111,部门管理,ums:department,path,/system/department.html,layui-icon layui-icon-console,,1,,100
112,新建部门,ums:department:create,auth,,,,0,,111
113,修改部门,ums:department:update,auth,,,,0,,111
114,删除部门,ums:department:delete,auth,,,,0,,111
115,查询部门,ums:department:read,auth,,,,0,,111
116,员工管理,ums:user,path,/system/user.html,layui-icon layui-icon-console,,4,,100
117,新增员工,ums:user:create,auth,,,,0,,116
118,修改员工,ums:user:update,auth,,,,0,,116
119,查询员工,ums:user:read,auth,,,,0,,116
120,查询员工,ums:user:read,auth,,,,0,,116
124,工作空间,,menu,,layui-icon layui-icon-console,,1,,0
125,工作台,,path,/view/console/index.html,layui-icon layui-icon-console,,2,_component,124
126,首页,,path,/view/analysis/index.html,layui-icon layui-icon-console,,1,_component,124
id,name,code,desc,rights_ids
1,超级管理员,super_admin,,100:101:102:103:104:105:106:107:109:108:110:111:112:113:114:115:116:117:118:119:120:124:125:126
2,普通管理员,admin,,106:107:109:108:110:111:112:113:114:115:116:117:118:119:120
3,普通用户,user,,111:112:113:114:115:116:117:118:119:120
id,nickname,username,password,mobile,email,avatar,department_id,role_ids
1,admin,超级管理员,123456,15543526531,8540854@qq.com,,1,1
2,就眠仪式,就眠仪式,123456,155324324234,8540854@qq.com,,1,2
3,zhengxinonly,正心全栈编程,123456,18675867241,pyxxponly@gmail.com,,1,1

后续需要获取项目的根目录,所以提前在配置文件中设置一下

python
class BaseConfig:
    SECRET_KEY = os.getenv("SECRET_KEY", "pear-admin-flask")

    SQLALCHEMY_DATABASE_URI = ""

    ROOT_PATH = os.path.dirname(os.path.abspath(__file__))  #

然后在 extensions 目录中添加初始化数据的配置脚本

python
import csv
import os

from flask import Flask, current_app

from pear_admin.extensions import db
from pear_admin.orms import DepartmentORM, RightsORM, RoleORM, UserORM


def dict_to_orm(d, o):
    for k, v in d.items():
        if k == 'password':
            o.password = v
        else:
            setattr(o, k, v or None)


def csv_to_databases(path, orm):
    with open(path, encoding="utf-8") as file:
        for d in csv.DictReader(file):
            o = orm()
            dict_to_orm(d, o)
            db.session.add(o)
            db.session.flush()
        db.session.commit()


def register_script(app: Flask):
    @app.cli.command()
    def init():
        db.drop_all()
        db.create_all()

        root = current_app.config.get("ROOT_PATH")

        rights_data_path = os.path.join(
            root, "static", "data", "ums_rights.csv"
        )
        csv_to_databases(rights_data_path, RightsORM)

        role_data_path = os.path.join(root, "static", "data", "ums_role.csv")
        csv_to_databases(role_data_path, RoleORM)

        with open(role_data_path, encoding="utf-8") as file:
            for d in csv.DictReader(file):
                role: RoleORM = RoleORM.query.get(d["id"])
                id_list = [int(_id) for _id in d["rights_ids"].split(":")]
                role.rights_list = RightsORM.query.filter(
                    RightsORM.id.in_(id_list)
                ).all()
                db.session.commit()

        department_data_path = os.path.join(
            root, "static", "data", "ums_department.csv"
        )
        csv_to_databases(department_data_path, DepartmentORM)

        user_data_path = os.path.join(root, "static", "data", "ums_user.csv")
        csv_to_databases(user_data_path, UserORM)

        with open(user_data_path, encoding="utf-8") as file:
            for d in csv.DictReader(file):
                user: UserORM = UserORM.query.get(d["id"])
                id_list = [int(_id) for _id in d["role_ids"].split(":")]
                user.role_list = RoleORM.query.filter(RoleORM.id.in_(id_list)).all()
                db.session.commit()

最后在 pear_admin/extensions/__init__.py 文件中配置到 app 对象上

python
from flask import Flask

from .init_db import db, migrate
from .init_script import register_script  #


def register_extensions(app: Flask):
    db.init_app(app)
    migrate.init_app(app, db)
    register_script(app)  #

执行 flask init 指令之后就会生成对应的数据。