zoukankan      html  css  js  c++  java
  • python练习---模拟sql

    要求:实现模拟sql登录,增删改查功能

    #_*_conding:utf-8_*_
    import os
    
    #登录验证部分
    
    status_dic = {
        'username': None,     #设置一个登录用户
        'status': False,      #用于后面验证是否登录,登录状态
    }
    
    def wrapper(func):  #登录验证的装饰器
        def inner1():
            if status_dic['status']:
                ret = func()
                return ret
            else:
                print("请先进行登录")
                if login():
                    ret = func()
                    return ret
        return inner1
    
    
    
    
    
    
    def login(*args):   #登录模块
        with open("login.txt", encoding="utf-8", mode="r") as f:
            login_list = f.readlines()
        if args:                          #判断用户是否登录
            status_dic['username'] = args[0]
            status_dic['status'] = True
            return True
        else:
            count = 0
            while count < 3:
                if status_dic['status'] == False:
                    username = input("请输入登录用户名:").strip()
                    for i in login_list:
                        if username == eval(i)["name"]:     #对用户名进行检查,看是否存在,不存在直接走for循环的else判断,让用户进行注册
    
                            password = input("请登录用户密码:").strip()
                            if password == eval(i)["password"]:  #判断密码输入是否正确
    
                                print("login successfully")
                                status_dic['username'] = username
                                status_dic['status'] = True
                                return sql_main()
                            else:
                                print("您还有%s次机会" % int(2 - count))  #3次机会验证,都错误会返回登录首页
                                count += 1
                                break
    
                    else:
                        print("检查用户名未注册...")
                        y = input("是否注册(yes/no):").strip()
                        if y == "yes" or y =="y":
                            return register()
    
                        elif y == "no" or y == "n":
                            return home_page()
                        else:
                            print("输入错误...")
            else:
                print("错误太多次啦...")
    
    
    def register():     #注册模块
        tag = True
        f1 = open("login.txt", encoding="utf-8", mode="r")
        login_list = f1.readlines()
        print("账号注册".center(50,"#"))
        while tag:
            username = input("请输入您注册的用户名:").strip()
            for i in login_list:
                if username == eval(i)["name"]:
                    print("用户名已经存在,请重新输入")
                    f1.close()
                    break
            else:
                password = input("请输入您注册的密码:").strip()
                f2 = open("login.txt",encoding="utf-8",mode="a")
                f2.write("{}
    ".format({"name": username,"password": password}))
                tag = False
                print("注册成功")
                f2.close()
                return login(username, password)
    
    
    
    def log_out():
        print("%s用户已注销" % status_dic['username'])
        status_dic['username'] = None
        status_dic['status'] = False
    
    
    def Quit_exit():
        print("退出程序...")
        return exit()
    
    
    
    
    def home_page():
        dic = {
            1: login,
            2: register,
            3: sql_main,
            4: log_out,
            5: Quit_exit
        }
    
        while True:
            print('1:登录用户
    2:注册用户
    3:执行sql
    4:注销
    5:退出程序')
    
            bianhao = input("请输入选择的序列号:").strip()
            if bianhao.isdigit():
                bianhao = int(bianhao)
                if 0 < bianhao <= 8:
                    dic[bianhao]()
                else:
                    print("输入编号不在范围内")
            else:
                print("输入的序列号只能是数字")
    
    
    #sql主程序,只有登录成功后才可以执行sql语句
    s = '''
    支持的sql语法
    1:insert
      insert into user values 张三,20,13412345678,BOSS
    2:delete
      delete from user where id =6
    3:update
      update user set name = Tom where id > 5
    4:select
      select * from user
      select name,age from user where age > 2
      select * from user where job='IT'
      select * from user where phone like 133
    '''
    @wrapper
    def sql_main():
        print('33[0;31m%s33[0m' % s)
        while True:
            sql = input("sql>").strip()
            if sql == 'exit': break
            if len(sql) == 0: continue
    
            sql_dic = sql_parse(sql)
            # print('main res is %s' % sql_dic)
    
            if len(sql_dic) == 0:
                print('sql语法不正确')
                continue
            res = sql_action(sql_dic)
            # print('33[41;1m%s33[0m' % res[-1])
    
            if type(res) is list:
                try:
                    for i in res[-1]:
                        if type(i) is str:
                            print(i.strip())
                        else:
                            print(i)
                    print("
    共计查询出%s条数据" % len(res[1]))
                except TypeError:
                    pass
            else:
                print(res)
    
    
    #sql处理部分
    #第一部分:sql解析
    def sql_parse(sql):  #insert delete update select
        '''
        把sql字符串切分,提取命令信息,分发给具体的解析函数去解析
        :param sql:
        :return:
        '''
    
        parse_func = {
            'insert': insert_parse,
            'delete': delete_parse,
            'update': update_parse,
            'select': select_parse
        }
    
        #print('sql str is %s' % sql)
        sql_l = sql.split()
        func = sql_l[0]
        res = ''
        if func in parse_func:
            res = parse_func[func](sql_l)
    
        return res
    
    
    
    def insert_parse(sql_l):
        '''
        定义insert语句的语法结构,执行sql解析操作,返回sql_dic
        :param sql:
        :return:
        '''
        sql_dic = {
            'func': insert,
            'insert': [],
            'into': [],
            'values': []
        }
        return handle_parse(sql_l,sql_dic)
    
    def delete_parse(sql_l):
        '''
        定义delete语句的语法结构,执行sql解析操作,返回sql_dic
        :param sql:
        :return:
        '''
        sql_dic = {
            'func': delete,
            'delete': [],
            'from': [],
            'where': []
        }
        return handle_parse(sql_l,sql_dic)
    
    def update_parse(sql_l):
        '''
        定义update语句的语法结构,执行sql解析操作,返回sql_dic
        :param sql:
        :return:
        '''
        sql_dic = {
            'func': update,
            'update': [],
            'set': [],
            'where': []
        }
        return handle_parse(sql_l, sql_dic)
    
    def select_parse(sql_l):
        '''
        定义select语句的语法结构,执行sql解析操作,返回sql_dic
        :param sql:
        :return:
        '''
        # print('from in the select_parse 33[41;1m%s33[0m' % sql_l)
        sql_dic = {
            'func':select,
            'select': [],  #查询字段
            'from': [],    #数据库.表
            'where': [],   #过滤条件
            'limit': []    #limit条件
        }
        return handle_parse(sql_l,sql_dic)
    
    
    
    def handle_parse(sql_l,sql_dic):
        '''
        执行sql解析操作,返回sql_dic
        :param sql_l:
        :param sql_dic:
        :return:
        '''
        # print('sql_l is 33[40;1m%s033[0m 
    sql_dic is 33[39;1m%s033[0m' %(sql_l,sql_dic))
        tag = False
        for i in sql_l:
            if tag and i in sql_dic:
                tag = False
            if not tag and i in sql_dic:
                tag = True
                key = i
                continue
            if tag:
                sql_dic[key].append(i)
        if sql_dic.get('where'):
            sql_dic['where'] = where_parse(sql_dic.get('where'))   #['id>4','and','id<10']
        # print('from in the handle_parse sql_dic is 33[40;1m%s33[0m' % sql_dic)
        return sql_dic
    
    
    def where_parse(where_l):   #['id>','4','and','id','<10']  -->  ['id>4','and','id<10']
        res = []
        key = ['and','or','not']
        char = ''
        for i in where_l:
            if len(i) == 0:continue
            if i in key:  #i为key当中存放的逻辑运算符
                if len(char) != 0:
                    char = three_parse(char)
                    res.append(char)  #char = 'id>4' ---> char = '['id','>','4']'
                res.append(i)
                char = ''
            else:
    
                char += i  #'id>4'
        else:
            char =  three_parse(char)
            res.append(char)
        #['id>4','and','id<=10'] --> [['id','>','4'],'and',['id','<=','10']]
        # print('from in the where_parse res is 33[40;1m%s33[0m' % res)
    
        return res
    
    def three_parse(str_l):
        #'id<=10'  --->  '['id','<=','10']'
        key = ['>','<','=']
        res = []
        char = ''
        opt = ''
        tag = False
        for i in str_l:
            if i in key:
                tag = True
                if len(char) != 0:
                    res.append(char)
                    char = ''
                opt += i
    
            if not tag:
                char += i
    
            if tag and i not in key:
                tag = False
                res.append(opt)
                opt = ''
                char += i
        else:
            res.append(char)
    
    
        #新增解析like的功能
        if len(res) == 1:
            res = res[0].split('like')
            res.insert(1,'like')
        # print('from in the three_parse res is 33[43;1m%s33[0m' % res)
        return res
    
        #第二部分:sql执行
    def sql_action(sql_dic):
        '''
        从字典sql_dic提取命令,分发给具体的命令执行函数去执行
        :param sql_dic:
        :return:
        '''
        return sql_dic.get('func')(sql_dic)
    
    
    def insert(sql_dic):
        #'insert': [], 'into': ['user'], 'values': ['a,23,11103213123,BOSS']
        # print('insert %s' % sql_dic)
        count = -1
        table = sql_dic.get('into')[0]
        f1 = open('%s' % table,'r',encoding='utf-8')
        for i in f1:
            if len(i.strip()) != 0:
                count += 1
        f1.close()
        with open('%s' % table,'a+',encoding='utf-8') as f2:
            value = sql_dic.get('values')[0]
            if len(value.strip().split(',')) == 4:
                f2.write('
    %s,%s' % (int(count+1),value))
                print('insert successful')
            else:
                print('缺少字段')
    
        return value
    
    
    
    def delete(sql_dic):
        #'delete': [], 'from': ['user'], 'where': [['id', '>', '2']]
    
        # print('delete %s' % sql_dic)
        table = sql_dic.get('from')[0]
        table_bak = '%s.bak' % table
        with open('%s' % table, 'r', encoding='utf-8') as read_f,open('%s' % table_bak,'w') as write_f:
            lines = read_f.readline().strip()
    
            tag = True
            for line in read_f:
                if tag:
                    write_f.write('%s
    '%lines)
                    write_f.flush()
                    tag = False
                dic = dict(zip(lines.split(','), line.split(',')))
                filter_res = logic_action(dic, sql_dic.get('where'))
                if not filter_res:
                    write_f.write(line)
    
            write_f.flush()
        os.remove("%s" % table)
        os.rename("%s" % table_bak, "%s" % table)
        print('delete successful')
        return
    
    
    
    def update(sql_dic):
        #'update': ['user'], 'set': ['id', '=', "'TT'"], 'where': [['name', 'like', 'dog']]}
        #print('update %s' %sql_dic)
        table = sql_dic.get('update')[0]
        table_bak = '%s.bak' % table
        with open('%s' % table, 'r', encoding='utf-8') as read_f,open('%s' % table_bak,'w') as write_f:
            lines = read_f.readline().strip()
            tag = True
            for line in read_f:
                if tag:
                    write_f.write('%s
    ' % lines)
                    write_f.flush()
                    tag = False
                dic = dict(zip(lines.split(','), line.split(',')))
                set = where_parse(sql_dic['set'])
    
                filter_res = logic_action(dic, sql_dic.get('where'))
                if not filter_res:
                    write_f.write(line)
                else:
                    old_list = lines.split(',')
                    old_index = old_list.index(set[0][0])
                    old = line.split(',')[old_index]
                    new = set[0][2]
                    line = line.replace(old,new)
                    write_f.write(line)
            write_f.flush()
        os.remove("%s" % table)
        os.rename("%s" % table_bak, "%s" % table)
        print('update successful')
        return
    
    def select(sql_dic):
        # print('from select sql_dic is %s' % sql_dic)
    
        #第一部分处理:from
        table = sql_dic.get('from')[0]
    
        f = open('%s' % table,'r',encoding='utf-8')
        lines = f.readline()
    
        #第二部分处理:where
        filter_res = where_action(f,sql_dic.get('where'),lines)
        # for i in filter_res:
        #     print('filter res is %s' % i)
    
        #第三部分处理:limit
        limit_res = limit_action(filter_res,sql_dic.get('limit'))
        # for i in limit_res:
        #     print('limit_res res is %s' % i)
        #第四部处理:select
        search_res = search_action(limit_res,sql_dic.get('select'),lines)
    
        f.close()
        return search_res
    
    
    
    def where_action(f,where_l,lines):
        # print('in where_action 33[41;1m%s33[0m'%whele_l)
    
        res = []
        if len(where_l) != 0:
            for i in f:
                dic = dict(zip(lines.strip().split(','),i.strip().split(',')))   #文件中的一条记录和where_L全部内容进行比对
    
                #逻辑判断
                logic_res = logic_action(dic,where_l)
                if logic_res:
                    res.append(i.split(','))
        else:
            res = f.readlines()
    
        return res
    
    
    
    
    def logic_action(dic,where_l):
        res = []
        # where_l = [['name', 'like', 'alex'], 'or', ['id', '<', '4'], 'or', ['id', '=', '1']]
        for i in where_l:
            if type(i) is list:
                i_k, opt, i_v = i
                if i[1] == '=':
                    opt = '%s=' % i[1]
                if dic[i_k].isdigit():
                    dic_v = dic[i_k]
                else:
                    dic_v = "'%s'" % dic[i_k]
                if opt != 'like':
                    i = str(eval("%s%s%s" % (dic_v, opt, i_v)))
                else:
                    if i_v in dic_v:
                        i = 'True'
                    else:
                        i = 'False'
            res.append(i)
        res = eval(' '.join(res))
        # print('==33[45;1m%s33[0m' %(res))
        return res
    
    def limit_action(filter_res,limit_l):
        res = []
        if len(limit_l) != 0:
            index = int(limit_l[0])
            res = filter_res[0:index]
        else:
            res = filter_res
    
        return res
    
    
    
    
    def search_action(limit_res,select_l,lines):
        res = []
        fileds_l = []
        if select_l[0] == '*':
            res = limit_res
            fileds_l = lines.split(',')
    
        else:
            for i in limit_res:
                dic = dict(zip(lines.split(','),i))
                r_l = []
                fileds_l = select_l[0].split(',')
                for line in fileds_l:
                    r_l.append(dic[line].strip())
                res.append(r_l)
    
        # print('search_action r_l %s,%s' % (fileds_l,r_l))
        return [fileds_l,res]
    
    
    
    
    if __name__ == '__main__':
        home_page()
  • 相关阅读:
    《mysql必知必会》学习_第23章_20180809
    禁止电脑自动乱装流氓软件
    网络地址转换技术NAT
    闲置手机作电脑无线音箱
    TransMac工具制作MacOS启动U盘
    制作MacOS启动U盘
    解决centos7启动后出现Warning: dracut-initqueue timeout‘ at startup进入emergency mode的问题
    思科 锐捷命令行简介
    VRRP 虚拟网关冗余协议
    STP 生成树协议
  • 原文地址:https://www.cnblogs.com/watchslowly/p/9022032.html
Copyright © 2011-2022 走看看