PYTHON解析SQL文件,提取其中的每条SQL

背景
.sql文件存放的是数据库的建表,插入,查询等sql,现在需要python连接数据库去执行sql文件中的所有操作。通过数据库客户端工具或者查询窗口可以批量执行。但是使用pymysql没有直接执行sql文件的方法。替代路线是解析sql文件内容成每条可单独执行的sql语句。然后一次循环excute。所以这里的核心问题是如何解析sql文件。
首先根据;切分显然不适合,不能正确解析插入内容中带有;的sql。还有一些建表语句是换行存在sql文件中的,简单的按行处理也不适合。为了适配这些情况,直接上代码。
给一个sql文件样例,内容如下:



-- ----------------------------
-- Table structure for t_dg_mdatt_catalog
-- ----------------------------
DROP TABLE IF EXISTS t_catalog;
CREATE TABLE t_catalog (
  MD_ID varchar(32) NOT NULL COMMENT '元数据id',
  DEFAULT_CHARACTER_SETNAME varchar(1000) DEFAULT NULL COMMENT '默认字符集名',
  DEFAULT_COLLATION_NAME varchar(1000) DEFAULT NULL COMMENT '默认校检名称',
  IP varchar(1000) DEFAULT NULL COMMENT 'IP地址',
  CREATE_TIME varchar(16) DEFAULT NULL COMMENT '创建时间',
  UPDATE_TIME varchar(16) DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (MD_ID)
)  COMMENT='目录属性表';
insert into TEST_TB (ID, CODE, NAME, PARENT_ID, REFERENCE_STANDARDS, DESCRIBES, SORT, DELETE_FLAG, CREATE_TIME, CREATE_USER, UPDATE_TIME, UPDATE_USER,TENANT_ID)
values ('00000000675e54b401675e5765550003', '01', '国标;\n', '0', '国标;\n', '国标', 1, '0', '20181129152045', 'sadmin', '20181129152045', 'sadmin','1');
-- commit;

commit;
处理的代码如下:
def readsql_from_file(sqlfile_path):
    try:
        mylogger.info("sql文件%s,开始内容转化" % (sqlfile_path))
        print("sql文件%s,开始内容转化" % (sqlfile_path))
        fp = open(sqlfile_path, 'r', encoding='utf-8')
        sql_str = fp.readlines()
        # results_list = sql_str.split(";")
        results, results_list = [], []
        ##去除\n\r
        if sql_str[-1].endswith(";"):
            sql_str[-1] = sql_str[-1] + "\n"
        for sql in sql_str:
            if sql.startswith( "\n") or sql == "\r":
                continue
            if sql.startswith("--"):
                continue
            # 去除数据中的“\n”和“\r”字符
            # if sql.endswith("\n"):
            #     sql = sql[::-1].replace("\n", "",1)[::-1]
            #     if sql.endswith("\r"):
            #         sql = sql[::-1].replace("\r", "",1)[::-1]

            # sql = sql.replace("\n", "").replace("\r", "")
            # 获取不是“--”开头且不是“--”结束的数据
            if not sql.startswith("--") and not sql.endswith("--"):
                if not sql.startswith("/*"):
                    results.append(sql)

        trmp_res_sql_list, res_sql_list = [], []
        while len(results) > 0:
            for i in range(len(results)):
                if results[i].endswith(";\n"):
                    tem_str = "".join(results[:i + 1])
                    trmp_res_sql_list.append(tem_str)
                    del results[:i + 1]
                    break
        # print(len(trmp_res_sql_list))
        for i in trmp_res_sql_list:
            if i.endswith(";\n"):
                i = i.strip()
                # i= i.replace(";\n","",1)
                i = i[::-1].replace(";", "", 1)[::-1]
                # i = i[::-1].replace(";\n", "", 1)[::-1]
                # print(str(i))
                res_sql_list.append(i)
        mylogger.info("sql文件%s,内容转化成功,转化待执行sql共%s条" % (sqlfile_path, str(len(res_sql_list))))
        print("sql文件%s,内容转化成功,转化待执行sql共%s条" % (sqlfile_path, str(len(res_sql_list))))
        return res_sql_list
    except Exception as ex:
        mylogger.error("sql文件%s,内容转化失败,错误信息%s" % (sqlfile_path, str(ex)))
        print("ERROR,sql文件%s,内容转化失败,失败信息%s" % (sqlfile_path, str(ex)))
        return None
if __name__ == "__main__":
	sql_list = readsql_from_file('./try.sql')
    for sql_str in range(len(sql_list)):
        print("第%s条SQL"%(str(sql_str)),sql_list[sql_str])


调用结果如下

sql文件./try.sql,开始内容转化
sql文件./try.sql,内容转化成功,转化待执行sql共4条
第0条SQL DROP TABLE IF EXISTS t_catalog
第1条SQL CREATE TABLE t_catalog (
  MD_ID varchar(32) NOT NULL COMMENT '元数据id',
  DEFAULT_CHARACTER_SETNAME varchar(1000) DEFAULT NULL COMMENT '默认字符集名',
  DEFAULT_COLLATION_NAME varchar(1000) DEFAULT NULL COMMENT '默认校检名称',
  IP varchar(1000) DEFAULT NULL COMMENT 'IP地址',
  CREATE_TIME varchar(16) DEFAULT NULL COMMENT '创建时间',
  UPDATE_TIME varchar(16) DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (MD_ID)
)  COMMENT='目录属性表'2条SQL insert into TEST_TB (ID, CODE, NAME, PARENT_ID, REFERENCE_STANDARDS, DESCRIBES, SORT, DELETE_FLAG, CREATE_TIME, CREATE_USER, UPDATE_TIME, UPDATE_USER,TENANT_ID)
values ('00000000675e54b401675e5765550003', '01', '国标;\n', '0', '国标;\n', '国标', 1, '0', '20181129152045', 'sadmin', '20181129152045', 'sadmin','1')3条SQL commit

你可能感兴趣的:(SQL解析,python)