11.17总结
概要:redis服务器连接,sql操作,JSON序列化,树
1. 新项目运行
- 删除原虚拟环境(venv)
- 配置编辑器为合适版本
- 配置运行编辑器为合适版本
- 导包
2. Redis服务器连接

安装完毕后以管理员权限打开redis-cli.exe,设置临时密码
# 查看密码
config get requirepass
# 设置密码
config set requirepass [password]
# 删除密码
config set requirepass ''
# 登录
auth [password]
# 清空
clear
或者打开redis.windows.conf,搜索requirepass,取消注释后修改密码
项目需要配置对应密码
3. SQL操作
配置信息
# 在config文件中配置
SQLALCHEMY_DATABASE_URI = 'mysql+cymysql://root:123456@127.0.0.1:3306/database_name'
带事务管理的数据库实例
class SQLAlchemy(_SQLAlchemy):
@contextmanager
def auto_commit(self):
try:
yield self.session
self.session.commit()
except Exception as e:
self.session.rollback()
raise e
finally:
if self.session:
self.session.close()
dbs = SQLAlchemy(app)
模型
class Department(dbs.Model):
__tablename__ = "department"
id = Column(String(10), primary_key=True, comment="部门ID")
parent_id = Column(String(10), comment="父部门ID")
name = Column(String(128), nullable=True, comment="部门名")
def __init__(self,id,parent_id,name):
self.id = id
self.parent_id = parent_id
self.name = name
增
# 这里self.get_data()是一个将数据转成json字典的函数
# 根据GET/POST类型使用request.args.get("key")/request.get_json()
# ----------------------------------------------
def add_department(self):
"""添加单个部门"""
data = self.get_data()
# 确定数据非空
if not data.get('id'):
return Success(data={"message":"部门ID不能为空"})
if not data.get('parent_id'):
return Success(data={"message":"上级部门ID不能为空"})
if not data.get('name'):
return Success(data={"message":"部门名称不能为空"})
# 添加数据
with dbs.auto_commit() as db:
# ID查询
d = db.query(Department).filter(Department.id == data.get('id')).first()
p_d = db.query(Department).filter(Department.id == data.get('parent_id')).first()
# 检查ID是否存在
if d:
return Success(data={"message":"部门已存在"})
# 检查上级部门是否存在
if not p_d and data.get('parent_id') != data.get('id'):
return Success(data={"message":"上级部门不存在"})
# 添加部门
db.add(Department(data.get('id'),data.get('parent_id'),data.get('name')))
return Success(data={"message":"OK"})
@api.route("/department/add",methods=['POST'])
def add_department():
d = DepartmentService()
return d.add_department()
{
"id":"000",
"parent_id": "000",
"name": "总部门"
}
批量添加数据
def batch_add_department(self):
"""批量添加数据"""
data = self.get_data()
departments = data.get("departments")
# 确定数据非空
if not departments:
return Success(data={"message":"部门数据为空"})
# 限制数据量
if len(departments) > 100:
return Success(data={"message":"单次添加部门不能超过100个"})
# 成功添加数据数
count = 0
# 添加数据
with dbs.auto_commit() as db:
# 构建类self.get_data()的列表,进行数据校验
# 查询所有数据
all_data = db.query(Department).all()
list = [ d.id for d in all_data ]
# 数据合法校验
# ----
res = {
"message": "",
"count":f'新增{count}条数据',
}
# 遍历请求数据
for index,data in enumerate(departments):
id = data.get('id')
parent_id = data.get("parent_id")
name = data.get("name")
# 确定数据非空
if not id:
res["message"] = "检查到当前部门没有ID数据,已停止"
return Success(data=res)
if not parent_id:
res["message"] = f"检查到ID为{id}的部门没有上级部门ID,已停止"
return Success(data=res)
if not name:
res["message"] = f"检查到ID为{id}的部门没有部门名称,已停止"
return res
# 检查ID重复情况
if id in list:
continue
# 检查P_ID重复情况
if not parent_id in list and parent_id != id:
# 检查P_ID是否在新增数据中
res["message"] = f"检查到ID为{id}的部门没有上级部门ID,已停止"
return Success(data=res)
# 创建部门
db.add(Department(id,parent_id,name))
# 更新list
list.append(id)
# 更新成功操作数
count += 1
res["count"] = f'新增{count}条数据'
res["message"] = "OK"
return Success(data=res)
@api.route("/department/add/batch",methods=['POST'])
def batch_add_department():
d = DepartmentService()
return d.batch_add_department()
{
"departments":[
{
"id":"000",
"parent_id":"000",
"name":"总部门"
},
{
"id":"001",
"parent_id":"000",
"name":"1号部门"
},
{
"id":"002",
"parent_id":"000",
"name":"2号部门"
},
{
"id":"003",
"parent_id":"000",
"name":"3号部门"
},
{
"id":"00001",
"parent_id":"001",
"name":"1-1号部门"
},
{
"id":"00002",
"parent_id":"001",
"name":"1-2号部门"
},
{
"id":"00003",
"parent_id":"001",
"name":"1-3号部门"
},
{
"id":"00004",
"parent_id":"002",
"name":"2-1号部门"
},
{
"id":"00005",
"parent_id":"002",
"name":"2-2号部门"
},
{
"id":"00006",
"parent_id":"002",
"name":"2-3号部门"
},
{
"id":"00007",
"parent_id":"003",
"name":"3-1号部门"
},
{
"id":"00008",
"parent_id":"003",
"name":"3-2号部门"
},
{
"id":"00009",
"parent_id":"003",
"name":"3-3号部门"
},
{
"id":"0000001",
"parent_id":"00001",
"name":"1-1-1号部门"
},
{
"id":"0000002",
"parent_id":"00001",
"name":"1-1-2号部门"
},
{
"id":"0000003",
"parent_id":"00001",
"name":"1-1-3号部门"
},
{
"id":"0000004",
"parent_id":"00002",
"name":"1-2-1号部门"
},
{
"id":"0000005",
"parent_id":"00002",
"name":"1-2-2号部门"
},
{
"id":"0000006",
"parent_id":"00002",
"name":"1-2-3号部门"
}
]
}
删
def delete_department(self):
"""删除单个部门"""
data = self.get_data()
id = data.get('id')
# 确认数据非空
if not id:
return Success(data={"message":"部门ID不能为空"})
# 删除数据
with dbs.auto_commit() as db:
department = db.query(Department).filter(Department.id == id).first()
# 检查部门是否存在
if not department:
return Success(data={"message":"部门不存在"})
# 检查部门是否有子部门
child = db.query(Department).filter(Department.parent_id == id).first()
if child:
return Success(data={"message":"该部门存在子部门,不能删除"})
db.delete(department)
return Success(data={"message":"OK"})
@api.route("/department/delete",methods=['POST'])
def delete_department():
d = DepartmentService()
return d.delete_department()
{
"id":"0000006"
}
# ------------------
{
"id":"001"
}
删除部门及其子部门
def batch_delete_department(self):
"""删除部门及其子部门"""
data = self.get_data()
id = data.get('id')
# 确认数据非空
if not id:
return Success(data={"message":"部门ID不能为空"})
# 删除数据
with dbs.auto_commit() as db:
department = db.query(Department).filter(Department.id == id).first()
# 检查部门是否存在
if not department:
return Success(data={"message":"部门不存在"})
# 获取子树
tree = self.get_tree(db,department.id)
# 子树+自身=待删除列表
res = {
"id":department.id,
"parent_id":department.parent_id,
"name":department.name,
"child":tree
}
# 从列表中提取ID
id_list = [ d["id"] for d in tree ]
id_list.append(department.id)
# 删除信息
db.query(Department).filter(Department.id.in_(id_list)).delete(synchronize_session=False)
return Success(data=res)
# 获取子树列表
def get_tree(self,db,parent_id):
data = db.query(Department).filter(Department.parent_id == parent_id).all()
child = []
for item in data:
d = {
"id":item.id,
"parent_id":item.parent_id,
"name":item.name,
"child":self.get_tree(db,item.id),
}
child.append(d)
return child def batch_delete_department(self):
"""删除部门及其子部门"""
data = self.get_data()
id = data.get('id')
# 确认数据非空
if not id:
return Success(data={"message":"部门ID不能为空"})
# 删除数据
with dbs.auto_commit() as db:
department = db.query(Department).filter(Department.id == id).first()
# 检查部门是否存在
if not department:
return Success(data={"message":"部门不存在"})
# 取树
res = get_tree(db,department.id)
# 从列表中提取ID
id_list = [ d["id"] for d in res ]
id_list.append(department.id)
# 删除信息
# _in:SQLAlchemy 中的查询操作符,用于生成 SQL 中的 IN 子句
# synchronize_session=False:不尝试同步会话中的对象状态
db.query(Department).filter(Department.id.in_(id_list)).delete(synchronize_session=False)
return Success(data=res)
@api.route("/department/delete/batch",methods=['POST'])
def batch_delete_department():
d = DepartmentService()
return d.batch_delete_department()
{
"id":"001"
}
查
def get_department(self):
"""
获取部门
传入id时查询单个部门及其子部门
不传入id查询所有部门
"""
data = self.get_data()
id = data.get("id")
with dbs.auto_commit() as db:
departments = db.query(Department).all()
res = get_tree(menu_list=self.query_to_list(departments), pid=id if id else "000", p_key_name="parent_id")
return Success(data=res)
@api.route("/department/query",methods=['POST'])
def get_department_byid():
d = DepartmentService()
return d.get_department()
{
}
# --------------------
{
"id":"001"
}
改和批量改
def update_department(self):
"""根据ID修改部门信息"""
data = self.get_data()
id = data.get('id')
# 确认数据非空
if not id:
return Success(data={"message":"没有要修改的部门ID"})
# 构建修改数据键值对,ID不进行修改
set_data = {
k:v for k,v in data.items() if k != "id"
}
# 确认修改非空
if not set:
return Success(data={"message":"没有要修改的值"})
# 修改数据合法校验
# ---
with dbs.auto_commit() as db:
department = db.query(Department).filter(Department.id == id).first()
# 确认数据非空
if not department:
return Success(data={"message":"没有对应ID的部门"})
# 更新数据
db.query(Department).filter(Department.id == id).update(set_data)
return Success(data={"message":"OK"})
def batch_update_department(self):
"""批量修改数据"""
data = self.get_data()
departments = data.get("departments")
# 确定数据非空
if not departments:
return Success(data={"message":"部门数据为空"})
# 限制数据量
if len(departments) > 100:
return Success(data={"message":"单次修改部门不能超过100个"})
# 成功修改数据数
count = 0
# 修改数据
with dbs.auto_commit() as db:
# 构建类self.get_data()的列表,进行数据校验
# 查询所有数据
all_data = db.query(Department).all()
list = [ d.id for d in all_data ]
# 数据合法校验
# ----
res = {
"message": "",
"count":f'成功修改了{count}条数据',
}
# 遍历请求数据
for index,data in enumerate(departments):
id = data.get('id')
parent_id = data.get("parent_id")
name = data.get("name")
# 确定数据非空
if not id:
res["message"] = "检查到当前修改没有对应部门ID,已停止"
return Success(data=res)
if not parent_id and not name:
# 没有要修改的数据
continue
# 检查ID重复情况
if id not in list:
res["message"] = f"检查到ID为{id}的部门不存在,已停止"
return Success(data=res)
continue
# 检查P_ID重复情况
if not parent_id in list and parent_id != id:
# 检查P_ID是否在原数据中
res["message"] = f"检查到ID为{id}的部门没有上级部门ID,已停止"
return Success(data=res)
# 创建部门
db.query(Department).filter(Department.id == id).update(data)
# 更新成功操作数
count += 1
res["count"] = f'成功修改了{count}条数据'
res["message"] = "OK"
return Success(data=res)
生成树
# 尝试对超出迭代深度的解决
def get_tree(menu_list: list = None, pid: str = 'id', key_name: str = 'id', p_key_name: str = 'pid',children: str = 'children'):
if menu_list is None:
return []
# 构建节点键值对
node_map = {item[key_name]: item for item in menu_list}
# 构建树
tree = []
# 遍历list
for item in menu_list:
# 如果是根节点下同一层的节点,添加到树后面
if item[p_key_name] == pid:
tree.append(item)
else:
# 否则获取他的父节点
parent = node_map.get(item[p_key_name])
# 如果父节点存在,添加到父节点的孩子里
if parent:
# 添加孩子属性
if children not in parent:
parent[children] = []
# 添加孩子节点
parent[children].append(item)
# 移除空的孩子
for item in menu_list:
if children in item and not item.get(children):
del item[children]
return tree
79

被折叠的 条评论
为什么被折叠?



