一、简介

关于Python如何连接数据库并执行SQL语句,几乎所有的Python教程都会讲,教程里基本只介绍了执行单条SQL语句的方法,但是实际生产过程中可不只是执行一两条语句,动辄几十条甚至上百条的SQL语句,一个.SQL的SQL文件正常都会包含多条SQL语句,如果把这些SQL语句直接贴进Python代码文件,势必会影响代码的可读性和美感,代码量也冗余,那么Python能不能像oracle的PL/SQL客户端或者navicat一样读取SQL文件并且执行会是一件非常有趣的事情。

经过不断百度和尝试,一段优雅的Python代码终于敲出来,作为开源的忠实粉丝,技术始于分享,现将Python执行SQL文件的代码分享在CSDN,代码实例是MySQL数据库。

二、原理实现

我们知道,mysql的语句执行时,默认是以分号结尾的。因此,只要将整个sql文件读取,以分号切割,就可以得到sql语句。

sql文件,内容如下:

USE test;
/*迁移用户信息*/
INSERT INTO `users` (
`UID`,
`USERNAME`,
`PASSWORD`,
`ROLE`,
`CREATE_TIME`
) SELECT
`id`,
`username`,
`password`,
`level`,
`create_time`
FROM
tbl_users;

使用python切割以分号切割,打印的sql还是很多行。因此需要将换行符,替换为空格。末尾增加分号结尾

with open('test.sql',encoding='utf-8',mode='r') as f:
# 读取整个sql文件,以分号切割。[:-]删除最后一个元素,也就是空字符串
sql_list = f.read().split(';')[:-]
for x in sql_list:
# 判断包含空行的
if '\n' in x:
# 替换空行为1个空格
x = x.replace('\n', ' ') # sql语句添加分号结尾
sql_item = x+';'
print(sql_item)

执行输出:

USE test;
/*迁移用户信息*/ INSERT INTO `users` ( `UID`, `USERNAME`, `PASSWORD`, `ROLE`, `CREATE_TIME` ) SELECT `id`, `username`, `password`, `level`, `create_time` FROM tbl_users;

可以发现,会有很多空行。可以再加一个判断,进行替换

with open('test.sql',encoding='utf-8',mode='r') as f:
# 读取整个sql文件,以分号切割。[:-1]删除最后一个元素,也就是空字符串
sql_list = f.read().split(';')[:-1]
for x in sql_list:
# 判断包含空行的
if '\n' in x:
# 替换空行为1个空格
x = x.replace('\n', ' ') # 判断多个空格时
if ' ' in x:
# 替换为空
x = x.replace(' ', '') # sql语句添加分号结尾
sql_item = x+';'
print(sql_item)

执行输出:

USE test;
/*迁移用户信息*/ INSERT INTO `users` ( `UID`, `USERNAME`, `PASSWORD`, `ROLE`, `CREATE_TIME` ) SELECT `id`, `username`, `password`, `level`, `create_time` FROM tbl_users;

三、正式代码

上面的步骤已经得到完整的sql语句了,那么就可以使用pymysql模块来执行每一句sql了。

环境说明

原始表结构为:

CREATE TABLE `tbl_users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL DEFAULT '' COMMENT '用户名',
`password` char(32) NOT NULL DEFAULT '' COMMENT '密码',
`level` tinyint(10) NOT NULL DEFAULT '' COMMENT '用户等级',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='用户表';

目标表结构为:

CREATE TABLE `users` (
`UID` bigint(20) NOT NULL AUTO_INCREMENT,
`USERNAME` varchar(20) NOT NULL DEFAULT '' COMMENT '用户名',
`PASSWORD` char(32) NOT NULL DEFAULT '' COMMENT '密码',
`ROLE` varchar(20) NOT NULL DEFAULT '' COMMENT '角色',
`CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`UID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='用户表';

需要将原始表的数据,迁移到目标表中。

mysql服务器ip为 192.168.10.104,用户名和密码都是root,使用test数据库。

完整代码

完整代码如下:

#!/usr/bin/env python3
# coding: utf-8
import pymysql try:
db = pymysql.connect("192.168.10.104", "root", "root", "test")
c = db.cursor()
with open('test.sql',encoding='utf-8',mode='r') as f:
# 读取整个sql文件,以分号切割。[:-1]删除最后一个元素,也就是空字符串
sql_list = f.read().split(';')[:-1]
for x in sql_list:
# 判断包含空行的
if '\n' in x:
# 替换空行为1个空格
x = x.replace('\n', ' ') # 判断多个空格时
if ' ' in x:
# 替换为空
x = x.replace(' ', '') # sql语句添加分号结尾
sql_item = x+';'
# print(sql_item)
c.execute(sql_item)
print("执行成功sql: %s"%sql_item)
except Exception as e:
print(e)
print('执行失败sql: %s'%sql_item)
finally:
# 关闭mysql连接
c.close()
db.commit()
db.close()

执行输出:

执行成功sql: USE test;
执行成功sql: /*迁移用户信息*/ INSERT INTO `users` ( `UID`, `USERNAME`, `PASSWORD`, `ROLE`, `CREATE_TIME` ) SELECT `id`, `username`, `password`, `level`, `create_time` FROM tbl_users;

本文参考链接:

https://blog.csdn.net/jsyzliuyu/article/details/79632995

python代码执行SQL文件(逐句执行)的更多相关文章

  1. 使用Python批量修改数据库执行Sql文件

    由于上篇文章中批量修改了文件,有的时候数据库也需要批量修改一下,之前的做法是使用宝塔的phpMyAdmin导出一个已经修改好了的sql文件,然后依次去其他数据库里导入,效率不说极低,也算低了,且都是些 ...

  2. PHP执行.SQL文件的实例代码分享

    介绍下使用PHP执行.SQL文件的代码一例,分享下. demo.php: <?php ) )) ) ENGINE) unsigned ) unsigned )) ) ENGINE) unsign ...

  3. C#和Java中执行SQL文件脚本的代码(非常有用)

    原文:C#和Java中执行SQL文件脚本的代码(非常有用) 我们在做程序的时候有事后会涉及到利用sql文件 直接执行,可是在sql文件中有很多注释,我们要一句一句的执行首先必须的得把sql文件解析 去 ...

  4. 利用PHP执行SQL文件,将SQL文件导入到数据库

    如何利用php自动执行.sql文件.其实很简单,就是获取sql文件中的内容,然后将每一句sql语句一次执行就行啦. 这是代码 //读取文件内容 $_sql = file_get_contents('t ...

  5. MySQL命令执行sql文件的两种方法

    MySQL命令执行sql文件的两种方法 摘要:和其他数据库一样,MySQL也提供了命令执行sql脚本文件,方便地进行数据库.表以及数据等各种操作.下面笔者讲解MySQL执行sql文件命令的两种方法,希 ...

  6. shell调用sqlplus批量执行sql文件

    在最近的工作中,经常需要批量执行一些DML, DDL, PL/SQL语句或导入一些Function, Procedure.因为support的国家比较多,常常需要一个登陆到一个国家的数据库上执行完成后 ...

  7. 使用java以及jdbc不使用第三方库执行sql文件脚本

    使用java以及jdbc不使用第三方库执行sql文件脚本 2017年02月15日 15:51:45 阅读数:660 使用java执行sql脚本的方法 解析sql脚本,删除不必要的注释和空行 将语句按分 ...

  8. python代码在linux终端中执行报错:Unable to init server: Could not connect: Connection refused

    python代码在linux终端中执行时报错: Unable to init server: Could not connect: Connection refused Unable to init ...

  9. MySQL学习系列一---命令行连接mysql和执行sql文件

    1.命令行连接mysql #mysql -h(主机) -u(用户名) -p (数据库名) mysql -hlocalhost -uroot -p testdb Enter password: **** ...

随机推荐

  1. Sublime Text 3关闭自动升级提醒

    由于种种原因,导致不想升级现有版本的ST3,但是被它的升级提醒弹窗严重骚扰! ||||||||||| 解 决 办 法 ||||||||||| 1.首选项 - 设置 - 用户(快捷键 ❀,)打开“Pre ...

  2. ELK实时日志分析平台环境部署,以及可视化展示

    ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件.新增了一个FileBeat,它是一个轻量级的日志收集处理工具(Agent) ...

  3. Eclipse4.9集成Tomcat 9.0.21详细版

    1.下载Tomcat 从Tomcat官网下载:https://tomcat.apache.org 此处我下载的版本是Tomcat 7.0.94 下载完毕后解压即可,我解压后的路径是D:\soft\ap ...

  4. redis渐进式rehash机制

    在Redis中,键值对(Key-Value Pair)存储方式是由字典(Dict)保存的,而字典底层是通过哈希表来实现的.通过哈希表中的节点保存字典中的键值对.我们知道当HashMap中由于Hash冲 ...

  5. linux 下查看redis是否启动

    make make PREFIX=/usr/local/redis install mkdir /etc/redis/ cp redis.conf /etc/redis/ 打开redis.conf文件 ...

  6. java.lang.IllegalStateException: No instances www.xxxx.com available for localhost

    在SpringCloud的项目中,我们使用了自动配置的OAuth2RestTemplate,RestTemplate,但是在使用这些restTemplate的时候,url必须是服务的名称,如果要调用真 ...

  7. systemctl enable rc-local.service error

    /******************************************************************************* * systemctl enable ...

  8. Cross-channel Communication Networks

    Cross-channel Communication Networks 2019-12-13 14:17:18 Paper: https://papers.nips.cc/paper/8411-cr ...

  9. BaiduPCS-Go的安装及使用

    BaiduPCS-Go的安装及使用 linux下会提示输入验证码,浏览器打开验证码url,多输入几次 Contents [hide] 一. 软件下载及安装 二. 软件的使用 1. 账号登录与退出 2. ...

  10. 浅析String.intern()方法

    1.String类型“==”比较样例代码如下:package com.luna.test;public class StringTest { public static void main(Strin ...