Python自定义形参在函数调用:字典解包与setattr在数据库(DjangoORM+Sqlalchemy)中的实战使用

知识点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

希望对你有用,有问题可以留言哦,如果不错的话点个赞吧^^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值