之前有群友反应同事给了他一个几百MB的sql脚本,导入数据库再从数据库读取数据有点慢,想了解下有没有可以直接读取sql脚本到pandas的方法。

解析sql脚本文本文件替换成csv格式并加载

我考虑了一下sql脚本也就只是一个文本文件而已,而且只有几百MB,现代的机器足以把它一次性全部加载到内存中,使用python来处理也不会太慢。

我简单研究了一下sql脚本的导出格式,并根据格式写出了以下sql脚本的读取方法。

注意:该读取方法只针对SQLyog导出的mysql脚本测试,其他数据库可能代码需要根据实际情况微调。

读取方法:

from io import StringIO

import pandas as pd

import re

def read_sql_script_all(sql_file_path, quotechar="'") -> (str, dict):

insert_check = re.compile(r"insert +into +`?(\w+?)`?\(", re.I | re.A)

with open(sql_file_path, encoding="utf-8") as f:

sql_txt = f.read()

end_pos = -1

df_dict = {}

while True:

match_obj = insert_check.search(sql_txt, end_pos+1)

if not match_obj:

break

table_name = match_obj.group(1)

start_pos = match_obj.span()[1]+1

end_pos = sql_txt.find(";", start_pos)

tmp = re.sub(r"\)( values |,)\(", "\n", sql_txt[start_pos:end_pos])

tmp = re.sub(r"[`()]", "", tmp)

df = pd.read_csv(StringIO(tmp), quotechar=quotechar)

dfs = df_dict.setdefault(table_name, [])

dfs.append(df)

for table_name, dfs in df_dict.items():

df_dict[table_name] = pd.concat(dfs)

return df_dict

参数:

sql_file_path:sql脚本的位置

quotechar:脚本中字符串是单引号还是双引号,默认使用单引号解析

返回:

一个字典,键是表名,值是该表对应的数据所组成的datafream对象

下面我测试读取下面这个sql脚本:

其中的表名是index_test:

df_dict = read_sql_script_all("D:/tmp/test.sql")

df = df_dict['index_test']

df.head(10)

结果:

可以看到能顺利的直接从sql脚本中读取数据生成datafream。

当然上面写的方法是一次性读取整个sql脚本的所有表,结果为一个字典(键为表名,值为datafream)。但大部分时候我们只需要读取sql脚本的某一张表,我们可以改造一下上面的方法:

def read_sql_script_by_tablename(sql_file_path, table_name, quotechar="'") -> (str, dict):

insert_check = re.compile(r"insert +into +`?(\w+?)`?\(", re.I | re.A)

with open(sql_file_path, encoding="utf-8") as f:

sql_txt = f.read()

end_pos = -1

dfs = []

while True:

match_obj = insert_check.search(sql_txt, end_pos+1)

if not match_obj:

break

start_pos = match_obj.span()[1]+1

end_pos = sql_txt.find(";", start_pos)

if table_name != match_obj.group(1):

continue

tmp = re.sub(r"\)( values |,)\(", "\n", sql_txt[start_pos:end_pos])

tmp = re.sub(r"[`()]", "", tmp)

df = pd.read_csv(StringIO(tmp), quotechar=quotechar)

dfs.append(df)

return pd.concat(dfs)

参数:

sql_file_path:sql脚本的位置

table_name:被读取的表名

quotechar:脚本中字符串是单引号还是双引号,默认使用单引号解析

返回:

该表所对应的datafream对象

读取代码:

df = read_sql_script_by_tablename("D:/tmp/test.sql", "index_test")

df.head()

结果:

将sql脚本转换为sqlite格式并通过本地sql连接读取

在写完上面的方法后,我又想到另一种解决思路,就是将sql脚本转换成sqlite语法的sql语句,然后直接加载。各种类型的数据库的sql语句变化较大,下面的方法仅针对SQLyog导出的mysql脚本测试通过,如果是其他的数据库,可能下面的方法仍然需要微调。最好是先自行将sql脚本转换为sqlite语法的sql语句后,再使用我写的方法加载。

加载sql脚本的方法:

from sqlalchemy import create_engine

import pandas as pd

import re

def load_sql2sqlite_conn(sqltxt_path):

create_rule = re.compile("create +table [^;]+;", re.I)

insert_rule = re.compile("insert +into [^;]+;", re.I)

with open(sqltxt_path, encoding="utf-8") as f:

sqltxt = f.read()

engine = create_engine('sqlite:///:memory:')

pos = -1

while True:

match_obj = create_rule.search(sqltxt, pos+1)

if match_obj:

pos = match_obj.span()[1]

sql = match_obj.group(0).replace("AUTO_INCREMENT", "")

sql = re.sub("\).+;", ");", sql)

engine.execute(sql)

match_obj = insert_rule.search(sqltxt, pos+1)

if match_obj:

pos = match_obj.span()[1]

sql = match_obj.group(0)

engine.execute(sql)

else:

break

tablenames = [t[0] for t in engine.execute(

"SELECT tbl_name FROM sqlite_master WHERE type='table';").fetchall()]

return tablenames, engine.connect()

参数:

sql_file_path:sql脚本的位置

返回:

两个元素的元组,第一个元素是表名列表,第二个元素是sqlite内存虚拟连接

测试读取:

tablenames, conn = load_sql2sqlite_conn("D:/tmp/test.sql")

tablename = tablenames[0]

print(tablename)

df = pd.read_sql(f"select * from {tablename};", conn)

df

结果:

到此这篇关于Pandas直接读取sql脚本的文章就介绍到这了,更多相关Pandas读取sql脚本内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

mysql读取sql脚本_Pandas直接读取sql脚本的方法相关推荐

  1. python读取excel指定列-Python读取excel指定列生成指定sql脚本的方法

    需求 最近公司干活,收到一个需求,说是让手动将数据库查出来的信息复制粘贴到excel中,在用excel中写好的公式将指定的两列数据用update这样的语句替换掉. 例如: 有个A库,其中有两个A.01 ...

  2. 从Mysql某一表中随机读取n条数据的SQL查询语句

    若要在i ≤ R ≤ j 这个范围得到一个随机整数R ,需要用到表达式 FLOOR(i + RAND() * (j – i + 1)).例如, 若要在7 到 12 的范围(包括7和12)内得到一个随机 ...

  3. MySQL:偏移量为 0x000000000ae000 的位置执行 读取 期间,操作系统已经向 SQL Server 返回了错误 21(设备未就绪。)。

    环境:SQL Server 问题是:在文件 'D:\Test\db.mdf' 中.偏移量为 0x000000000ae000 的位置执行 读取 期间,操作系统已经向 SQL Server 返回了错误 ...

  4. python sql逐行读取数据库数据,使用python读取数据库中的内容 把爬虫爬到的内容,存储在mysql数据库中...

    安装pymsql库 以管理员身份打开cmd,输入pip Install pymysql import pymysql #连接数据库 conn = pymysql.connect(hoost='loca ...

  5. mysql注入如何读取本地文件_如何通过SQL注入获取服务器本地文件

    写在前面的话 SQL注入可以称得上是最臭名昭著的安全漏洞了,而SQL注入漏洞也已经给整个网络世界造成了巨大的破坏.针对SQL漏洞,研究人员也已经开发出了多种不同的利用技术来实施攻击,包括非法访问存储在 ...

  6. python读取数据库数据类型_Python实现从SQL型数据库读写dataframe型数据的方法【基于pandas】...

    本文实例讲述了Python实现从SQL型数据库读写dataframe型数据的方法.分享给大家供大家参考,具体如下: Python的pandas包对表格化的数据处理能力很强,而SQL数据库的数据就是以表 ...

  7. 数据库读取前几条记录的SQL语句大全

    1. Oracle数据库 SELECT * FROM TABLENAME WHERE ROWNUM <= N 2. Infomix数据库 SELECT FIRST N * FROM TABLEN ...

  8. spark学习 Java版SparkSQL程序读取Hbase表注册成表SQL查询

    参考: spark学习-SparkSQL–11-scala版写的SparkSQL程序读取Hbase表注册成表SQL查询 http://blog.csdn.net/qq_21383435/article ...

  9. mysql rds 定时执行_RDS下执行SQL小脚本

    RDS下执行SQL小脚本 #!/bin/bash echo ' =============================== - 生产操作谨慎执行 - - - 提前预置SQL文件 - - ===== ...

最新文章

  1. java string改变的影响_为什么Java的string类要设成immutable(不可变的)
  2. Spring Cloud Stream消费失败后的处理策略(二):自定义错误处理逻辑
  3. libevent中的时间及相关的管理
  4. WM_PAINT消息小结
  5. es6 --- Reflect的静态方法
  6. mysql建库需要权限吗_mysql 建库报匿名用户权限错误
  7. GODIVA:只需一步,文字到视频秒级生成,微软亚洲研究院最新成果
  8. 图像处理-二值形态学运算
  9. Python语言编程规范与优化建议
  10. 6选择内核启动项_Linux内核都没搞懂,Alot和你还有什么关系?
  11. 交换机 路由器 OSI7层模型
  12. python用什么来写模块-史上最详细的python模块讲解
  13. Vue学习笔记之13-webpack的配置 傻子看了都会配置的超详细教程
  14. Improving Opencv9 Eroding and Dilating 和对opencv窗体上有控制按钮的理解
  15. WebCrack:网站后台弱口令批量检测工具 ——yzddMr6
  16. html超链接调用js函数,在html中引入外部js文件,并调用带参函数的方法
  17. 面向后端的前端技术分享
  18. 移动显示服务器异常,移动远程服务器异常
  19. oracle是gbk程序是utf8的,oracle数据库gbk转utf8
  20. C语言中【变量】的存储类型共有4种类型

热门文章

  1. 使用GDAL创建Erdas格式的金字塔
  2. ASP.NET 开发小技巧 (持续更新)
  3. 基于SLP协议的BCH黑客马拉松即将开展
  4. JAVA之间的引用传递
  5. weblogic 启动项目失败,JMS 队列通过http 方式访问
  6. 系统时间、时区、字符集
  7. C# 实现FTP上传与下载
  8. shell 流程控制语句
  9. 玩转SCVMM中的更新基线,实现虚拟平台基础服务器补丁自动更新
  10. Mozilla Firefox 54 今起支持开启e10s多进程功能