python操作mysql(pymysql,pandas,numpy,C++)类封装测试v1.1(tcy)

python操作mysql(pymysql,pandas,numpy, C++)类封装测试

本项目主要完成类的封装。

项目目的:
   通过python 操作mysql数据库

项目内容:
   1.pymysql操作mysql数据库。(适用对读写速度要求不高的场所 ,数据量中等。)
   2.pandas,numpy操作mysql数据库。(较快的数据读写,数据量适中)
   3.C++操作mysql数据库(最优也最难)

目前完成项目:
    数据库,表的封装        v1.0 完成      2019/1/20
    数据列属性的设置与修改  v1.1 完成 (添加支持返回类型可选list or dict)
    索引键自增             v1.2 完成      2019/2/27

    插入数据               v1.3 完成      2019/3/1
    查询                   v1.4 onging
    
    pandas,numpy封装      v0.1 ng
    c++封装                v0.1 ng   

封装进行中。。。。。。       欢迎大家分享,修改,指正。

    以上完成的经过全部测试,纯python环境;
    文档内容包括类目录,类测试,类原代码。

   懒人的办法,你不用再去记pymysql及mysql的指令,直接封装完成,直接调用。
版本v1.1
import re
import pymysql
# import mysql
# import MySQLdb
class PyMySqlClass(object): # 继承object类所有方法
    """
    writed by tcy in shanghai yexie in 2019/1/24--2/28
    Mysql语句pymsql的封装。你能通过这些方法执行数据库的读写创建等操作。

    pymysql connect参数:
    self, host=None, user=None, password='', database=None, port=0, unix_socket=None,
    charset='', sql_mode=None, read_default_file=None, conv=None, use_unicode=None, client_flag=0,
    cursorclass=<class 'pymysql.cursors.Cursor'>, init_command=None, connect_timeout=10,
    ssl=None, read_default_group=None, compress=None, named_pipe=None, autocommit=False,
    db=None, passwd=None, local_infile=False, max_allowed_packet=16777216, defer_connect=False,
    auth_plugin_map=None, read_timeout=None, write_timeout=None,
    bind_address=None, binary_prefix=False, program_name=None, server_public_key=None
    """
    __slots__=( 'db_name','n_row','con','cursor','err','war') # 用tuple定义允许绑定的属性名称

    __config = {
        'host': '127.0.0.1', 'port': 3306, 'user': 'root', 'password': 'root',
        'charset': '', 'database': None, 'connect_timeout': 10, 'autocommit': False,
        'max_allowed_packet': 16777216, 'read_timeout': None, 'write_timeout': None
    }
    def __init__(self ,is_SSDictCurse=False,**config):
        self.n_row = 0  # 查询结果影响的行数
        self.err = ''
        self.war = ''

        self.con = None
        self.cursor = None

        self.__connect_db(is_SSDictCurse, **self.__config)
        self.db_name=self.__config['database']

    def __del__(self):
        self.db_name = ''
        self.n_row = 0
        self.err = ''
        self.war = ''

        self.__close_connect()
    #0.数据库连接
    #==========================================================================================
    #0.1定义1个连接
    def __connect_db(self ,is_SSDictCurse=False,**config):
        """
        :param is_SSDictCurse: bool; 每个操作都独占一个连接,当前只能执行一个操作
        :param config: dict 连接配置参数;可指定数据库也可不指定
        :return: None 你能创建1个新的连接
        """
        if not bool(config):return -1
        for i in config:
            for i1 in self.__config:
                if i==i1:self.__config[i]=config[i]

        try:
            if is_SSDictCurse == False:  # 所有查询共用一个连接 _con,一个游标 _cursor
                _con = pymysql.connect(**self.__config)
                _cursor = _con.cursor(pymysql.cursors.DictCursor)  # 输出结果为字典
                # if autocommit: _con.autocommit(1)                # 自动提交事务
            else:                        # 每个操作都独占一个连接,当前只能执行一个操作
                _SScon = pymysql.connect(**self.__config)
                _SScursor = _SScon.cursor(pymysql.cursors.SSDictCursor)  # 迭代为字典

            self.con = _con if is_SSDictCurse == False else _SScon
            self.cursor = _cursor if is_SSDictCurse == False else _SScursor
            return None
        except Exception as  e:
            self.err = "DB Connect Error!" + str(e)
            return -1
    # 0.2关闭数据库连接
    def __close_connect(self):
        self.db_name='';self.err='';self.war='';self.n_row=0;
        if self.con :
            self.con.close()
            return None
        else:
            self.err = "DB close Error!.Not connect."
            return -1
    #==========================================================================================

    #1.数据库操作
    def __run(self,sql='',commit=False,fetchall=True,backvalue=True,executemany=False,args=None):
        '''
        你也能直接用此方法执行mysql语句
        :param sql: str;Mysql语句
        :param commit: bool;True提交更改
        :param fetchall: bool or int>0;False不返回数据,True返回全部数据;int返回指定数量数据
        :param backvalue: bool;为True返回数据
        :param executemany: True用executemany指令
        :param args: 指令参数
        :return: result[0]=None or 查询结果dict,result[1]成功执行返回None,失败返回-1
        '''
        self.n_row=0
        result=None;runok=None
        try:
            if executemany==False:
                # 执行SQL语句
                if args:
                    self.n_row = self.cursor.execute(sql, args)
                else:
                    self.n_row = self.cursor.execute(sql)
            else:
                    self.n_row=self.cursor.executemany(sql,args)#必须要有args参数
            if commit:
                self.con.commit()     # 提交到数据库执行
            if backvalue:
                if isinstance(fetchall,bool):
                    result = (self.cursor.fetchall() if fetchall else self.cursor.fetchone())
                elif isinstance(fetchall,int) and (fetchall>0):
                    result=self.cursor.fetchmany(fetchall)
        except Exception as  e:       # Exception 是所有异常的基类,这里表示捕获所有的异常
            self.con.rollback()       # 发生错误时回滚
            self.n_row =0;runok=-1
            self.err = "__run() Error!"+str(e)
        finally:
            return (result,runok)

    # 1.1 查看当前数据库
    def show_db_name_current(self):
        '''
        :return: 查看当前数据库--返回str
        '''
        sql = "select database()"
        lst = self.__run(sql)[0]
        return lst[0]['database()'] if lst else  None
    
    def get_db_name_current(self):
        return self.show_db_name_current()
    
    # 1.2 查看所有数据库
    def show_db_name_all(self):
        '''
        :return: 查看所有数据库--返回字符串list
        show create table m1809;#显示创建mysql命令str
        show table status;#Rows Auto_increment
        #显示数据库中数据表
        SELECT * FROM information_schema.tables WHERE Table_Schema='new_futures' having table_name='m1809';
           #TABLE_SCHEMA,TABLE_NAME,TABLE_ROWS,AUTO_INCREMENT,
        select * from information_schema.COLUMNS where TABLE_NAME='m1809';
           #TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME,COLUMN_DEFAULT()默认值,IS_NULLABLE,DATE_TYPE,
           COLUMN_TYPE,COLUMN_KEY,EXTRA,CHARACTER_SET_NAME,COLLATION_NAME

        '''
        sql = "show databases"
        lst = self.__run(sql)[0]
        return ( [i['Database'] for i in lst] if lst else None)

    def get_db_names(self):
        return self.show_db_name_all()

    #1.3 数据库是否存在
    def is_exist_db(self,db_name):
        sql="show databases like '%s'"%(db_name)
        result=self.__run(sql)
        return  bool(result[0]) and (result[1]==None)

    #1.4 数据库是否是当前数据库
    def is_exist_db_current(self,db_name):
        sql = "select database()"
        return  db_name in str(self.__run(sql)[0])

    #1.5 创建数据库
    def create_db(self,db_name,charset='UTF8MB4'):
        if  self.is_exist_db(db_name):return -1
        sql='CREATE DATABASE IF NOT EXISTS %s DEFAULT CHARACTER SET %s' % (db_name,charset)
        result=self.__run(sql,commit=True,backvalue=False)
        return result[1]
    # 1.5 创建数据库
    def add_db(self, db_name, charset='UTF8MB4'):
        return self.create_db(db_name,charset)

    #1.6 删除数据库
    def drop_db(self,db_name):
        if not self.is_exist_db(db_name):return -1
        sql='drop database if exists  %s ' % (db_name)
        result=self.__run(sql,commit=True,backvalue=False)
        if result[1]==-1:return -1
        if self.db_name==db_name:
            self.db_name=''
        return None
    #1.6 删除数据库
    def del_db(self, db_name):
        return self.drop_db(db_name)

    #1.7 选择数据库
    def select_db(self,db_name):
        '''
        Mysql语句:use new_futures;
        '''
        if not self.is_exist_db(db_name):return -1
        if not self.is_exist_db_current(db_name):
            self.con.select_db(db_name)
            self.db_name=db_name
        return None

    #2.表的操作
    #==========================================================================
    # 2.0显示所有表
    def show_tb_names(self,db_name=''):
        """
        :param db_name: 
        :return: 
         #显示数据库中数据表
        SELECT * FROM information_schema.tables WHERE Table_Schema='new_futures' having table_name='m1809';
           #TABLE_SCHEMA,TABLE_NAME,TABLE_ROWS,AUTO_INCREMENT,
        """
        db_name=db_name if db_name else self.get_db_name_current()
        
        # if db_name=='':
        #     if self.is_exist_db_current(db_name):
        #         sql = "show tables"
        #     else:
        #         return None
        # else:
        #     if self.is_exist_db(db_name):
        #         sql= "select table_name from information_schema.tables where table_schema = '%s'"%(db_name)
        #     else:
        #         return None
        # 
        # lst = self.__run(sql)[0];str_lst=None
        # if lst:
        #     str_lst = str(lst).replace('}', '').replace(':', ',').replace("]", '').replace("'", '').split(",")
        #     str_lst=[i.strip() for i in str_lst if i.find('{')==-1]
        return str_lst
    # 2.0显示所有表
    def get_tb_names(self,db_name=''):
        return self.show_tb_names(db_name)
    #2.1 修改表名
    def __alter_table_name(self, tb_old_name, tb_new_name):
        if (not self.is_exist_table(tb_old_name)) or self.is_exist_table(tb_new_name):
            return -1
        sql = 'rename table %s to %s' % (tb_old_name, tb_new_name)
        result=self.__run(sql, commit=True, backvalue=False)
        return result[1]
    #2.1 修改表名
    def rename_table(self, tb_old_name, tb_new_name):
        return  self.__alter_table_name(tb_old_name, tb_new_name)

    #2.2 删除表
    def drop_table(self, tb_name):
        if not self.is_exist_table(tb_name):return -1
        sql = "DROP TABLE if exists %s" % tb_name
        result=self.__run(sql,commit=True,backvalue=False)
        return result[1]
    def del_table(self, tb_name):
        return self.drop_table(tb_name)
    #2.3 复制表
    def copy_table(self, tb_old_name, tb_new_name, copy_data=False):
        '''
        :param tb_name: old table name
        :param tb_new_name: create new table name
        :param copy_all:true 复制数据,false仅仅拷贝表结构
        :return:None
        '''
        if not self.is_exist_table(tb_old_name):return -1
        copyall = 'like' if copy_data==False else 'as select * from'
        sql = 'create table if not exists %s %s %s' % (tb_new_name, copyall, tb_old_name)
        result=self.__run(sql, commit=True, backvalue=False)
        return result[1]

    #2.4 清空数据表
    def del_table_datas(self, tb_name,fast_del=True):#保留字段
        """
        :param tb_name: str
        :param fast_del: bool;快速删除表数据不能恢复
        :return: None
        """
        if not self.is_exist_table(tb_name):return -1
        sql = "truncate table " if fast_del else "DELETE FROM "
        sql = sql+"%s" % tb_name
        result=self.__run(sql,commit=True,backvalue=False)
        return result[1]
    #2.4 清空数据表
    def clear_table_datas(self,tb_name,fast_del=True):#保留字段
        return self.del_table_datas(tb_name,fast_del)

    #2.5 判断数据表是否存在
    def is_exist_table(self, tb_name):
        sql = "show tables like '%s'" % tb_name
        result = self.__run(sql)
        return bool(result[0]) and (result[1]==None)

    #2.6 创建数据表
    def create_table(self, tb_name, table_options):
        """
        MySQL format:
        create table if not exists tb_name (
                id bigint unsigned auto_increment primary key,#主键只能设1个
                user varchar(10) not null default '',
                createtime datetime) select_statement;        #加快速度

        Pymql format:
        '`id` bigint(11) NOT NULL AUTO_INCREMENT,'

        args:
                tb_name  :str   表名字
                table_options :dict:属性键值对,{'col_name':'varchar(20) NOT NULL'...}
                               str: 'col_name varchar(20) NOT NULL,...'
                foreign_key :str  主外键约束,PRIMARY KEY(`id`)
        """
        if  self.is_exist_table(tb_name): return -1
        if isinstance(table_options,str):
            temp_str=table_options
        else:
            temp_str = ''.join([''.join([' ',i,' ',v,',']) for i,v in table_options.items()])
            temp_str= '('+temp_str.rstrip(',')+')'

        sql = 'CREATE TABLE IF NOT EXISTS %s '%tb_name + temp_str
        result=self.__run(sql,commit=True,backvalue=False)
        return result[1]

    def add_table(self, tb_name, table_options):
        self.create_table(tb_name, table_options)
    #3.表结构
    #========================================================================
    # 修改表信息
    '''
    ALTER TABLE tb_name#增加一个字段 多个命令之间用逗号分割
            ADD col_name int not null  [FIRST|AFTER col_name1]   #添加字段
            ADD primary key (col_name1)                          #添加首键
            ADD [UNIQUE]  INDEX [index_name] (col_name1,...)     #添加索引
            ALTER col_name {SET DEFAULT 0 |DROP DEFAULT}         #修改默认值
            CHANGE col_name  int(5) not null auto_increment      #修改列属性
            DROP col_name           #删除列名
            DROP PRIMARY KEY        #删除首键
            DROP INDEX index_name   #删除索引
            RENAME  tb_new_name     #修改表名
     '''
    #3.1显示表结构
    def __show_cols_options(self,tb_name):
        if not self.is_exist_table(tb_name): return None
        sql='show full columns from %s '%(tb_name)
        return  self.__run(sql)[0]

    #3.2 显示表结构
    def __describe_cols_options(self,tb_name,col_name=''):
        '''
        :param tb_name: str
        :param col_name: str 模板包含%,_
        :return: list or None
        实例:DESC查询结果
        [{'Field':'date','Type':'date','Null':'YES','Key':'UNI','Default':'2019-01-28','Extra': ''},...]
        '''
        if not self.is_exist_table(tb_name):return None
        sql='DESC %s  %s '%(tb_name,col_name)
        return  self.__run(sql)[0]

    #3.3 获取表字段信息
    def columns(self, tb_name,col_name=''):
        '''
        :param tb_name: str
        :param col_name: str;返回dict指定列,缺失返回全部列类型options;只能指定1列
        :return: 返回dict{'field','type','null','key','default','extra'}
        '''
        field=[];type=[];null=[];key=[];default=[];extra=[]
        if  self.is_exist_table(tb_name):
            lst=self.__describe_cols_options(tb_name,col_name)
            if lst:
                for i in lst:
                    field.append(i['Field'])
                    type.append(i['Type'])
                    null.append(i['Null'])
                    key.append(i['Key'])
                    default.append(i['Default'])
                    extra.append(i['Extra'])
        return {'name':field,'field':field,'type':type,'null':null,'key':key,'default':default,'extra':extra}

    #3.4 显示字段名#返回str的list
    def show_cols_names(self, tb_name,col_name=''):
        return self.columns(tb_name,col_name)['field']
    def get_cols_names(self, tb_name,col_name=''):
        return self.show_cols_names(tb_name,col_name)
    #3.5 更改列名
    def rename_col(self, tb_name, col_name='',col_new_name=''):
        '''
        ALTER TABLE m1809 CHANGE col_name col_new_name int(5) [not null auto_increment]
        '''
        if not self.is_exist_table(tb_name) and not self.is_exist_col(tb_name,col_name):return -1
        if self.is_exist_col(tb_name,col_new_name):return -1
        type=self.columns(tb_name,col_name)['type']
        # if not bool(type):return -1
        # new_col_name=self.columns(tb_name,col_new_name)['name']
        # if new_col_name:return -1
        return self.repair_columns(tb_name, col_name, col_new_name, type[0])
       
    #3.6 列名是否存在判断
    def __is_exist_cols(self,tb_name,cols_names='',cols_options='',all=False):
        """
        :param tb_name: str
        :param cols_names: str;类似'id,name,age,...'最后无逗号
        :param cols_options: str;
               类似"id int not null,name varchar(10) default '',..."最后无逗号
        :return: bool
        """

        if not self.is_exist_table(tb_name):return False
        cols_names_=self.get_cols_names(tb_name)
        if not bool(cols_names_):return False
        cols_names_=[i.lower() for i in cols_names_]

        if cols_names!='':
            lst=cols_names.lower().split(',')
            result=[i for i in lst if i in cols_names_]
            return (all and len(result)==len(lst)) or ((not all) and (len(lst)>0))
        else:
            if cols_options=='':return False
            cols_options=cols_options.lower()
            lst=[i.split()[0] for i in cols_options.split(',')]

            result = [i for i in lst if i in cols_names_]
            return (all and len(result) == len(lst)) or ((not all) and (len(lst) > 0))

    def is_exist_col(self,tb_name,col_name=''):
        if not self.is_exist_table(tb_name):return False
        return col_name in self.columns(tb_name,col_name)['name']

    def any_exist_cols(self,tb_name,cols_names='',cols_options=''):
        """
        :param tb_name: str
        :param cols_names: str;类似'id,name,age,...'最后无逗号
        :param cols_options: str;
               类似"id int not null,name varchar(10) default '',..."最后无逗号
        :return: bool
        """
        return self.__is_exist_cols(tb_name,cols_names,cols_options,False)
    def all_exist_cols(self,tb_name,cols_names='',cols_options=''):
        return self.__is_exist_cols(tb_name,cols_names,cols_options,True)

    #3.7 获取首键唯一值索引的列名--返回字符串list
    def show_keys_names(self, tb_name):
        if not self.is_exist_table(tb_name):return None
        lst=self.columns(tb_name)['key']
        return lst if bool(lst) else None
    def get_keys_names(self, tb_name):
        return self.show_keys_names(tb_name)
    # 3.8 列是否是首键
    def is_exist_PRI_col(self, tb_name,col_name):
        if not self.is_exist_table(tb_name): return False
        lst = self.columns(tb_name, col_name)['key']
        return 'PRI' in lst

    # 3.9 表中是否存在首键
    def is_exist_PRI_tb(self, tb_name):
        if not self.is_exist_table(tb_name): return False
        lst = self.columns(tb_name)['key']
        return 'PRI' in lst
    # 3.10 列是否是唯一值键
    def is_exist_UNI_col(self, tb_name,col_name):
        if not self.is_exist_table(tb_name): return False
        lst = self.columns(tb_name, col_name)['key']
        return 'UNI' in lst
    # 3.11 表中是否存在唯一值键
    def is_exist_UNI_tb(self, tb_name):
        if not self.is_exist_table(tb_name): return False
        lst = self.columns(tb_name)['key']
        return 'UNI' in lst
    #3.12 获取列的数据类型--返回字符串list
    def show_cols_types(self, tb_name):
        if not self.is_exist_table(tb_name): return False
        lst= self.columns(tb_name)['type']
        return lst if bool(lst) else None

    def get_cols_types(self, tb_name):
        return self.show_cols_types(tb_name)

    #3.13 显示索引2019/2/24
    def show_indexs_names(self, tb_name):
        """
        :param tb_name: str
        :return: dict={'col_name':index_name,...}

        show index from m1809显示结果:
        [{'Table': 'm1809', 'Non_unique': 0, 'Key_name': 'PRIMARY', 'Seq_in_index': 1,
          'Column_name':    'No', 'Collation': 'A', 'Cardinality': 14, 'Sub_part': None,
          'Packed': None, 'Null': '', 'Index_type': 'BTREE', 'Comment': '',
          'Index_comment': '', 'Visible': 'YES', 'Expression': None},{...},...]
        本方法执行结果类似:
        {'No': 'PRIMARY', 'date': 'date_UNIQUE', 'open': 'idx_m1809_open_high', 'high': 'idx_m1809_open_high'}

        """
        d=dict()

        if not self.is_exist_table(tb_name):return d
        sql = 'show index from %s ' % (tb_name)
        lst = self.__run(sql)[0]
        if not bool(lst):return d
        for i in lst:
           d[ i['Column_name']]=i['Key_name']
        return d

    # 3.14 列是否是索引判断
    def is_exist_index_col(self, tb_name, col_name=''):
        '''
        :param tb_name:
        :param index_name:
        :return: bool

        show index from m1809;
        [{'Table': 'm1809', 'Non_unique': 0, 'Key_name': 'PRIMARY', 'Seq_in_index': 1,
          'Column_name': 'No', 'Collation': 'A', 'Cardinality': 7, 'Sub_part': None,
          'Packed': None, 'Null': '', 'Index_type': 'BTREE', 'Comment': '',
          'Index_comment': '', 'Visible': 'YES', 'Expression': None},{..},..]
        '''
        if not self.is_exist_table(tb_name): return False
        d=self.show_indexs_names(tb_name).keys()
        return col_name in d

    # 3.15 是否是索引名判断
    def is_exist_index_name(self, tb_name, index_name=''):
        if not self.is_exist_table(tb_name): return False
        d=self.show_indexs_names(tb_name).values()
        return index_name in d

    # 3.16 显示自增的列名
    def show_auto_increment_name(self, tb_name):
        """
        :param tb_name: str
        :return: str list

        语句:'show create table m1809;'
        [{'Table': 'm1809', 'Create Table': "CREATE TABLE `m1809` (\n
          `No` int(11) NOT NULL AUTO_INCREMENT,\n
          `name` char(20) NOT NULL,\n
          `code` char(10) DEFAULT 'm',\n
          `datetime` datetime DEFAULT '2019-01-28 22:46:30',\n
          `date` date DEFAULT '2019-01-28',\n
          `time` time DEFAULT '22:46:00',\n
          `open` float DEFAULT NULL,\n
          `high` float DEFAULT '300',\n
          `low` float DEFAULT '200',\n
          `close` float DEFAULT '200',\n
          `vol` int(11) DEFAULT '200',\n  PRIMARY KEY (`No`),\n
          UNIQUE KEY `date_UNIQUE` (`date`),\n
          KEY `idx_m1809_open_high` (`open`,`high`)\n)
          ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci"}]

        说明:自增只能设置1个
        """
        if not self.is_exist_table(tb_name): return None
        sql = 'show create table %s ' % (tb_name)
        auto_increment_col_name=str(self.__run(sql)[0])
        result=(re.findall(r"\\n\s*`(.*)`.*AUTO_INCREMENT,",auto_increment_col_name,re.I))
        return (result if result else None)
    #----------------------
    #3.17表中是否存在自增列
    def __is_exist_PRI_AI(self, tb_name):
        if not self.is_exist_table(tb_name): return False
        col_name=self.show_auto_increment_name(tb_name)
        if not bool(col_name):return False
        return self.is_exist_PRI_col(tb_name,col_name[0])
        
    #3.18获取列的mysql语句
    def get_col_order_str(self, tb_name,col_name):
        if not self.is_exist_table(tb_name): return None

        sql = 'show create table %s ' % (tb_name)
        lst=str(self.__run(sql)[0])

        p=r"\s+`"+col_name+r"`[\w\s()]+"
        result = (re.findall(p, lst, re.I))
        return result[0].replace('`','') if result else None

    #3.21 添加字段
    def add_cols(self, tb_name, cols_options=''):
        """
        :param tb_name: str
        :param cols_options: str;
               类似"id int not null,name varchar(10) default "Bob",..";最后无逗号
        :return: None
        
        Mysql语句:
        ALTER TABLE tb_name#增加一个字段 多个命令之间用逗号分割
            ADD col_name int not null  [FIRST|AFTER col_name1]  #添加字段
        """
        if not self.is_exist_table(tb_name):return -1
        if self.any_exist_cols(tb_name,cols_options=cols_options):return -1
        sql = 'alter table %s  add  %s ' % (tb_name,cols_options)
        result=self.__run(sql, commit=True,backvalue=False)
        return result[1]
         
    #3.22 删除字段
    def del_cols(self, tb_name,column_names=''):
        """
        :param tb_name: str
        :param column_names: str;类似"id,name,age,...";最后无逗号
        :return: None
        
        Mysql语句:
        ALTER TABLE tb_name #增加一个字段 多个命令之间用逗号分割
            DROP col_name   #删除列名
        """
        if not self.is_exist_table(tb_name): return -1
        if not self.all_exist_cols(tb_name,column_names):return -1
        sql = 'alter table %s drop %s ' % (tb_name,column_names)
        result=self.__run(sql, commit=True,backvalue=False)
        return result[1]
    
    #3.23 添加首键
    def add_primary_key(self, tb_name, pri_cols_names='',replace=False):
        """
        :param tb_name: str;
        :param pri_cols_names:str;类似"name,age,...";最后无逗号 
        :param replace:bool;False存在首键不替换,True存在首键替换
        :return: None
        
        Mysql语句:
        ALTER TABLE tb_name#增加一个字段 多个命令之间用逗号分割
            ADD primary key (col_name1,...)      #添加首键
        """
        if not self.is_exist_table(tb_name): return -1
        if self.is_exist_PRI_tb(tb_name) and not replace: return -1
        if self.is_exist_PRI_tb(tb_name) and replace:self.del_primary(tb_name)

        sql = 'alter table %s  add primary key ( %s )' % (tb_name, pri_cols_names)
        result=self.__run(sql, commit=True, backvalue=False)
        return result[1]

    #3.24 删除首键
    def del_primary_key(self, tb_name):
         '''
         Mysql语句:
         ALTER TABLE tb_name            #增加一个字段 多个命令之间用逗号分割
                DROP PRIMARY KEY        #删除首键
         '''
         if not self.is_exist_table(tb_name):return -1
         if not self.is_exist_PRI_tb(tb_name) :return -1
         if not self.__is_exist_PRI_AI(tb_name):
             # show_auto_increment_name
    
             sql = 'alter table %s drop primary key '%(tb_name)
             result=self.__run(sql, commit=True, backvalue=False)
    
             return result[1]

    def drop_primary_key(self, tb_name):
        return self.del_primary_key(tb_name)

    #3.25 添加索引
    def add_index(self, tb_name, index_name='',idx_cols_names='',unique=False):
        """
        :param tb_name: str;
        :param index_name: str;
        :param idx_cols_names: str;类似"id,name,...";最后无逗号
        :param unique: bool
        :return: None

        Mysql语句:
        ALTER TABLE tb_name#增加一个字段 多个命令之间用逗号分割
            ADD [UNIQUE]  INDEX [index_name] (col_name1,...)#添加索引
        注意:
            避免在同一列创建多个索引
        """
        if not self.is_exist_table(tb_name):return -1
        if self.is_exist_index_name(tb_name,index_name):return -1

        #避免在同一列创建多个索引
        d=self.show_indexs_names(tb_name)
        cols_names=idx_cols_names.split(',')
        if [i for i in d.keys() if i in cols_names]:return -1

        unique_str='' if unique==False else 'unique'
        sql = 'alter table %s add %s index %s ( %s ) '%(tb_name,unique_str,index_name,idx_cols_names)
        result=self.__run(sql, commit=True, backvalue=False)
        return result[1]

    #3.26 删除索引
    def __del_index(self, tb_name, index_name=''):
            sql = 'alter table %s drop index %s ' % (tb_name,index_name)
            result=self.__run(sql, commit=True, backvalue=False)
            return result[1]

    def del_indexs(self, tb_name, index_name=''):
        """
        :param tb_name: str
        :param index_name: str;如为空,删除全部
        :return: None

        DROP INDEX index_name on tb_name  #删除索引
        """
        b=None
        if not self.is_exist_table(tb_name):return -1
        if index_name=='':
            idx_names=self.show_indexs_names(tb_name).values()
            idx_names=[i for i in idx_names if i!='PRIMARY']
            if not bool(idx_names):return -1
            for i in idx_names:
                if(self.__del_index(tb_name,idx_names)):
                    b=-1
            return b
        else:
           return self.__del_index(tb_name,index_names)

    #3.27 修改默认值:数字型可为数字,str
    def add_default_value(self, tb_name, col_name='',default_value=''):
        ''''
        Mysql语句:
        ALTER TABLE tb_name#增加一个字段 多个命令之间用逗号分割
               ALTER col_name {SET DEFAULT 0 |DROP DEFAULT}         #修改默认值
        '''
        if self.is_exist_table(tb_name):
            sql = 'alter table %s alter %s set default %s ' % (tb_name, col_name,default_value)
            result=self.__run(sql, commit=True, backvalue=False)
            return result[1]
        else:
            return -1

    # 3.27 修改默认值:数字型可为数字,str
    def repair_default_value(self, tb_name, col_name='', default_value=''):
        return self.add_default_value(tb_name, col_name,default_value)
    #3.28 删除默认值
    def drop_default_value(self, tb_name, col_name=''):
        ''''
        Mysql语句:
        ALTER TABLE tb_name#增加一个字段 多个命令之间用逗号分割
               ALTER col_name {SET DEFAULT 0 |DROP DEFAULT}         #修改默认值
        '''
        if self.is_exist_table(tb_name):
            sql = 'alter table %s alter %s drop default ' % (tb_name, col_name)
            result=self.__run(sql, commit=True, backvalue=False)
            return result[1]
        else:
            self.err = tb_name + " not exist! drop_default_value() fail. "
            return -1

    def del_default_value(self, tb_name, col_name=''):
        return self.drop_default_value(tb_name, col_name)
    
    #3.30 更改列名并修改列属性--更改列名必须指定类型
    def repair_columns(self, tb_name, col_name='',col_new_name='',col_options=''):
        '''
        :param tb_name:
        :param col_name: str;旧列名
        :param col_options: str;字段属性;如 int(5) not null auto_increment
        :param col_new_name: str;修改的列名
        :return: None

        ALTER TABLE m1809 CHANGE col_name col_new_name int(5) [not null auto_increment]
        '''
        if self.is_exist_table(tb_name) and self.all_exist_cols(tb_name, col_name):
            b=(col_name != col_new_name)  and (not self.all_exist_cols(tb_name, col_new_name))
            if (col_name==col_new_name) or b:
                sql = 'alter table %s change %s %s %s'%(tb_name, col_name, col_new_name,col_options)
                result=self.__run(sql, commit=True, backvalue=False)
                return result[1]
        else:
            self.err = tb_name + " or "+col_name+" not exist! repair_columns() fail. "
            return -1

    #3.31 更改列的类型:
    def change_columns(self, tb_name, col_name='', col_options=''):
        '''
        ALTER TABLE m1809 CHANGE col_name col_new_name int(5) [not null auto_increment]
        '''
        return self.repair_columns(tb_name, col_name, col_name, col_options)

    #3.32 更改列的类型:
    def alter_columns(self, tb_name, col_name='',col_options=''):
        '''
        :param tb_name: str;
        :param col_name: str;
        :param col_options: str;列的类型
        :return: None

        ALTER TABLE t1 MODIFY column_b BIGINT NOT NULL
        '''
        if self.is_exist_table(tb_name)and self.all_exist_cols(tb_name, col_name):
            sql = 'Alter Table %s MODIFY %s %s' % (tb_name, col_name, col_options)
            result=self.__run(sql, commit=True, backvalue=False)
            return result[1]
        else:
            self.err = tb_name + " or " + col_name + " not exist! change_columns() fail. "
            return -1
    # ==========================================================================
    def select(self,tb_name='',columns=''):
        '''
        :param tb_name:
        :param columns: str;如id,name,age,...
        :return:
        '''
        columns='*' if columns=='' else columns
        # [{'no': 0, 'name': '豆粕', 'date': datetime.date(2018, 7, 9)}
        sql='SELECT %s FROM %s'%(columns,tb_name)
        return self.__run(sql)[0]


    #4.插入操作
    # ===========================================================================
    def insert_data(self, tb_name,columns=(),col_values=[],
                    repeat_value=False,updata_col_names='',priority='',executemany=True):
        '''
        MySql语句:
        INSERT[LOW_PRIORITY | DELAYED | HIGH_PRIORITY][IGNORE]#插入的优先级
                [INTO] tb_name[(字段1,...)]
                VALUES({值| DEFAULT},...),(...),
                [  ON DUPLICAE KEY UPDATE 字段名=表达式,...]#唯一键或首键重复时根据表达式修改数据

        用途:插入数据
        参数:
        tb_name:str;table name
        columns:str; 类似(“列名id","列名name",...)
        col_values:str list,类似[["123","Tom",...],[...],...]列名的长度和下面的赋值数量必须相等
        priority:str{'LOW_PRIORITY' | 'DELAYED' | 'HIGH_PRIORITY']['IGNORE'}#插入的优先级
        repeat_value:bool;True当出现unique key,primary key重复时系统自动修改;默认修改全部
        updata_col_names:str;当指定repeat_value=True,用本str列名更新,缺失修改全部列
        实例:
        insert into  m1809 (no,name,date) VALUES (7,'Bob2','2019-02-04'),(8,'Tom3','2019-02-05') on
               DUPLICATE KEY UPDATE name = VALUES(name);#当出现重复值时用新值替代旧值

        con=pymysql.connect( host='localhost',user='root',password='root',database='new_futures')
        cursor.executemany("INSERT INTO m1809 (No,name) VALUES (%s,%s)",
                   [['11','Tom'],['12','Bob'],['13','Jim']])
        con.commit()

        说明:用多行插入,采用executemany函数。必须指定参数executemany=True

        '''
        if  not self.is_exist_table(tb_name):
            self.err=tb_name+" not exist! intert data fail."
            return -1
        n=len(columns)
        sql="INSERT INTO "+tb_name+str(columns).replace("'",
            '').replace('"','')+" VALUES ("+ ('%s,'*n).rstrip(',') +  ")"
        if repeat_value:
            if updata_col_names:
               sql=sql+' on DUPLICATE KEY UPDATE name = VALUES(%s)'%(updata_col_names)
            else:
               sql = sql + ' on DUPLICATE KEY UPDATE name = VALUES(%s)' % (updata_col_names)
        result=self.__run(sql,commit=True,backvalue=False,executemany=True,args=col_values)#提升速度
        return result[1]

    #更新数据
    def update_data(self, tb_name,col_name_value,where_condition='',limit_n=0,priority=''):
        '''
        MySql语句:
            UPDATE[LOW_PRIORITY| IGNORE] 数据表名#优先级顺序
                SET 字段1=值1【,字段2=值2,...】
               【WHERE 条件表达式】
               【ORDER BY...】#限定表中被修改的行的次序
               【LIMIT 行数】 #限定被修改的行数

        实例:
        update m1809 set No=22,name="Smith" where name="Tom" limit 20
        '''
        if  not self.is_exist_table(tb_name):
            self.err=tb_name+' not exist! Updata data fail.'
            return -1
        where_con=" where "+where_condition  if where_condition!='' else ''
        limit_con=' limit ' +str(limit_n) if limit_n>0 else ''
        sql="UPDATE "+priority+" "+tb_name+" SET "+col_name_value+where_con+limit_con
        result=self.__run(sql,commit=True,backvalue=False)
        return result[1]

    #删除数据

    # def delete_data(self, tb_name,col_name_value,where_condition='',limit_n=0,priority=''):
    '''
    DELETE 【LOW_PRIORITY|QUICK】【IGNORE】FROM tb_name
                    【WHERE 条件表达式】
                    【ORDER BY...】
                    【LIMIT 行数】      #删除时会在事务日志中添加一条记录
    实例:
    delete from m1809 where id=11,user='Tom';
    #删除数据
    TRUNCATE TABLE 数据表名 #删除后无法恢复;不能删除参与索引和视图的表
    '''
        # if  not self.is_exist_table(tb_name):
        #     return
        # where_con=" where "+where_condition  if where_condition!='' else ''
        # limit_con=' limit ' +str(limit_n) if limit_n>0 else ''
        # sql="delete  "+priority+tb_name+" SET "+col_name_value+where_con+limit_con
        # self.__run(sql,commit=True,backvalue=False)
    # 4.查询操作
    # ==================================================
    # 5.索引操作
    # ==================================================
    # 3.插入操作
    # ==================================================
    # 3.插入操作
    # ==================================================

猜你喜欢

转载自blog.csdn.net/tcy23456/article/details/87909249