解决复杂问题的思路-排除法

1.排除法

在写代码的时候,我们经常会遇到这种情况,就是代码逻辑本身比较复杂,然后呢debug过程中还发现了一些很诡异的错误,比如如下python代码,其中Class 是班级对象,而 Student是学生对象,他们是一对多关系:

1.1.对象信息

class Class(Base):
    __tablename__ = 't_class'
    id = Column(INTEGER, primary_key=True, autoincrement=True)
    name = Column(String(32))

    def __init__(self, id=None, name=None):
        self.id = id
        self.name = name


class Student(Base):
    __tablename__ = 't_student'
    id = Column(INTEGER, primary_key=True, autoincrement=True)
    name = Column(String(32))
    c_id = Column('c_id', INTEGER)

    def __init__(self, id=None, name=None, c_id=c_id):
        self.id = id
        self.name = name
        self.c_id = c_id

2.获取数据库连接

class DBManager(object):
    @staticmethod
    def get_session():
        # postgresqls
        # engine = create_engine('postgresql://postgres:123456@10.74.12.202:5432/test', echo=True)
        # mysql
        engine = create_engine('mysql+mysqlconnector://root:123456@10.74.12.202:3306/test',
                               echo=False, encoding="utf-8", max_overflow=30, pool_size=10)
        DBsession = sessionmaker(bind=engine)
        # 初始化表

        return DBsession()

3.数据库信息
这里写图片描述
这里写图片描述
4.正常查询语句和结果
这里写图片描述
5.使用sqlalchemy查询语句
正常查询

def combine_query():
    """
    联合查询
    :return:
    """
    session = DBManager.get_session()
    query = session.query(Student.id, Student.name, Class.name).filter(Student.c_id == Class.id)
    rows = query.all()
    for row in rows:
        print row[0], row[1], row[2]

添加条件查询:添加 in 查询

def combine_query():
    """
    联合查询
    :return:
    """
    session = DBManager.get_session()
    query = session.query(Student.id, Student.name, Class.name).filter(Student.c_id == Class.id)
    ids = []
    query = query.filter(Student.id.in_(ids))
    rows = query.all()
    for row in rows:
        print row[0], row[1], row[2]

这个查询被 sqlalchemy 编译后的结果如下:

SELECT t_student.id AS t_student_id, t_student.name AS t_student_name, t_class.name AS t_class_name 
FROM t_student, t_class 
WHERE t_student.c_id = t_class.id AND t_student.id != t_student.id

注意where条件这一块多了如下的内容 AND t_student.id != t_student.id,这个很明显是有问题的,所以导致查询出错,因为这个查询很简单,所以如果多看看可能就把问题解决了。

但是如果这是一个非常复杂的查询,里面掺杂了各种查询条件,这个时候估计再来分析可能难度就会变得非常大,怎么办呢?比如如果代码如下:

def combine_query():
    """
    联合查询
    :return:
    """
    session = DBManager.get_session()
    query = session.query(Student.id, Student.name, Class.name).filter(Student.c_id == Class.id)
    ids = []
    query = query.filter(Student.name.like('小明'))
    query = query.filter(Student.c_id > 10)
    query = query.filter(Student.id.in_(ids))
    rows = query.all()
    for row in rows:
        print row[0], row[1], row[2]

这个时候,代码还是很简单,我们可以想象如果条件不是几个,而是几十个怎么办呢?对于这种复杂的问题,诡异的问题,不要去分析逻辑,那样太耗时了,直接使用排除法来解决,就是把所有条件都先删除掉,然后逐个添加条件,当添加某个条件后出现诡异问题了,那就说明问题就出现在这个条件上,然后就定位到问题了,解决的办法也就来了,这样的效率要比分析的效率高很多,因为掺杂逻辑的关联可能让分析变得非常麻烦和复杂,这种排除法反而简单而且容易分析。
对应上面这个问题,只要我们一个条件一个条件的添加,会发现出现AND t_student.id != t_student.id的时候是在添加: query = query.filter(Student.id.in_(ids)) 条件的时候,所以就知道是因为 ids 是空的时候会出现这种问题,于是我们就可以通过判断来决定是不是要添加这个条件了,我们可以修改如下。

def combine_query():
    """
    联合查询
    :return:
    """
    session = DBManager.get_session()
    query = session.query(Student.id, Student.name, Class.name).filter(Student.c_id == Class.id)
    ids = []
    query = query.filter(Student.name.like('小明'))
    query = query.filter(Student.c_id > 0)
    query = query.filter(Student.id.in_(ids) if ids else '')
    rows = query.all()
    for row in rows:
        print row[0], row[1], row[2]

如上可知道,我们使用的框架本身可能存在一些问题,这个时候如果我们正好碰上了,我们可能会感觉很受挫,这个时候,与其通过所谓的理性去查找问题,不如通过排除法来快速定位和解决问题,这会让我们解决问题的效率有很大提升

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值