知识点1:字典解包在Sqlalchemy中的使用:
我们在使用数据库时,经常会出现仅仅只想修改或获取几个字段的情况,但由于是在函数中调用,则只能通过字典解包方法进行操作;
测试环境:Python3.7
基础内容在此不再赘述,示例如下:
item = self.session.query(self.emp_class).filter_by(**filter_condition).first()
理解:建立一个会话以后,我们通过filter_by 方法进行字段条件过滤,这里使用 filter_condition 这个字典进行解包:
filter_condition = {
'JOB': 'xsy',
'DEPTNO': 66,
}
即:我们只想查看数据库 工作JOB 为 xsy(销售员),且在代号为66的DEPTNO(部门)的信息,解包相当于调用
item = self.session.query(self.emp_class).filter_by(JOB='xsy', DEPTNO=66).first()
这大大提高了函数的复用率
知识点2:使用setattr方法对Sqlalchemy进行属性赋值
同样,使用setattr也能增强函数复用性,即可以修改指定的某几个属性,该方法可以望文生义,代码参考全文如下:
from sqlalchemy import MetaData, Table, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
class DatabaseTools():
db_type = 'mysql+pymysql'
db_user = 'weiran'
db_pwd = 'password'
db_ip = '10.46.169.123'
db_port = 3306
emp_class = None # emp 表单反向映射类
session = None
def __init__(self, database):
"""
sqlalchemy数据库初始化
:param database: 连接的数据库名称
"""
# 创建数据库链接
db_engine = create_engine(f"{self.db_type}://{self.db_user}:{self.db_pwd}@{self.db_ip}:{self.db_port}/{database}", encoding='utf-8', echo=True)
print(f"{self.db_type}://{self.db_user}:{self.db_pwd}@{self.db_ip}:{self.db_port}/{database}")
metadata = MetaData(bind=db_engine) # 对DDL进行抽象(用于构建反向映射类)
AlchemyBase = declarative_base()
class EMP(AlchemyBase):
__table__ = Table("emp", metadata, autoload=True)
""" 要操作的表结构:
CREATE TABLE `emp` (
`EMPNO` int(4) DEFAULT NULL,
`ENAME` varchar(10) NOT NULL,
`JOB` varchar(9) DEFAULT NULL, # 工作岗位
`MGR` int(4) DEFAULT NULL, # 所属领导工号
`HIREDATE` date DEFAULT NULL,
`SAL` double(7,2) DEFAULT NULL, # 薪水
`COMM` double(7,2) DEFAULT NULL, # 津贴
`DEPTNO` int(2) DEFAULT NULL, # 部门代码
PRIMARY KEY (`ENAME`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
"""
self.emp_class = EMP
SessionClass = sessionmaker(bind=db_engine) # 创建顶级会话配置
self.session = SessionClass() # 创建和管理数据库连接的会话
# 通用更新单条emp表单数据
def update_emp_table(self, filter_condition, data_dct):
"""
# 通用更新单条emp表单数据
# 魏然 2020-6-9 09:09:16
:param filter_condition: 查询条件,字典类型
:param data_dct: 更新条件,字典类型
:return:
"""
# 更新标注数据包详情表单
item = self.session.query(self.emp_class).filter_by(**filter_condition).first()
# 更新字段
for key, value in data_dct.items():
setattr(item, key, value)
self.session.commit()
def test_database_tools():
filter_condition = {
'JOB': 'xsy',
'DEPTNO': 66,
}
data_dct = {
'COMM': 1000,
'MGR': 7639,
}
dt = DatabaseTools('my_test_db')
dt.update_emp_table(filter_condition, data_dct)
pass
if __name__ == '__main__':
test_database_tools()
知识点3:字典解包在DjangoORM中的使用
在DjangoORM中,也经常遇到我只想通过条件过滤到我想要的几个字段信息
这里只是示例,以Django中某个APP的 views.py 部分代码为例:
# 举例:DjangoORM,对WorkTask(工作任务表)操作:对该表有4个指定过滤条件
class WorkTaskViewSet(viewsets.ModelViewSet):
authentication_classes = [SysUserAuthentication, ]
serializer_class = WorkTaskSerializers
def get_queryset(self):
# print(self.request.query_params)
task_id = self.request.query_params.get('task_code')
task_status = self.request.query_params.get('task_status')
work_person_id = self.request.query_params.get('work_person_id')
check_person_id = self.request.query_params.get('check_person_id')
# 构造过滤条件
filter_condition = dict()
if task_id: filter_condition['task_id'] = task_id # 指定任务ID号
if task_status: filter_condition['task_status'] = task_status # 指定任务的状态
if work_person_id: filter_condition['work_person_id'] = work_person_id # 指定任务的实施人员ID
if check_person_id: filter_condition['check_person_id'] = check_person_id # 指定任务的检查人员ID
# 获取数据库中的数据
if filter_condition:
print(filter_condition)
queryset = WorkTask.objects.filter(**filter_condition) # 解包操作
# queryset = WorkTask.objects.filter(task_id=task_id) # 如果原始方法写,非常麻烦
else:
queryset = WorkTask.objects.all() # 如果没有指定条件,则获取全部信息
return queryset
希望对你有用,有问题可以留言哦,如果不错的话点个赞吧^^