Pandas直接读取sql脚本的方法


Posted in Python onJanuary 21, 2021

之前有群友反应同事给了他一个几百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脚本:

Pandas直接读取sql脚本的方法

其中的表名是index_test

df_dict = read_sql_script_all("D:/tmp/test.sql")
df = df_dict['index_test']
df.head(10)

结果:

Pandas直接读取sql脚本的方法

可以看到能顺利的直接从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()

结果:

Pandas直接读取sql脚本的方法

将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脚本的文章就介绍到这了,更多相关Pandas读取sql脚本内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python中的filter()函数的用法
Apr 27 Python
详解python时间模块中的datetime模块
Jan 13 Python
详解Python在七牛云平台的应用(一)
Dec 05 Python
使用Python制作微信跳一跳辅助
Jan 31 Python
Python实现简单生成验证码功能【基于random模块】
Feb 10 Python
Python matplotlib绘图可视化知识点整理(小结)
Mar 16 Python
pyspark.sql.DataFrame与pandas.DataFrame之间的相互转换实例
Aug 02 Python
对numpy下的轴交换transpose和swapaxes的示例解读
Jun 26 Python
Python实现PyPDF2处理PDF文件的方法示例
Sep 25 Python
python 字典有序并写入json文件过程解析
Sep 30 Python
使用Python封装excel操作指南
Jan 29 Python
安装不同版本的tensorflow与models方法实现
Feb 20 Python
python asyncio 协程库的使用
Jan 21 #Python
python palywright库基本使用
Jan 21 #Python
python Scrapy爬虫框架的使用
Jan 21 #Python
python 可视化库PyG2Plot的使用
Jan 21 #Python
详解基于Facecognition+Opencv快速搭建人脸识别及跟踪应用
Jan 21 #Python
Python实现石头剪刀布游戏
Jan 20 #Python
python程序实现BTC(比特币)挖矿的完整代码
Jan 20 #Python
You might like
虹吸式咖啡探讨–研磨
2021/03/03 冲泡冲煮
PHP实现微信公众平台音乐点播
2014/03/20 PHP
php进程间通讯实例分析
2016/07/11 PHP
WHOOPS PHP调试库的使用
2017/09/29 PHP
JQuery 学习笔记 选择器之二
2009/07/23 Javascript
jquery ui dialog里调用datepicker的问题
2009/08/06 Javascript
删除节点的jquery代码
2014/01/13 Javascript
Javascript核心读书有感之表达式和运算符
2015/02/11 Javascript
js判断主流浏览器类型和版本号的简单实现代码
2016/05/26 Javascript
关于JavaScript 原型链的一点个人理解
2016/07/31 Javascript
jQuery的ajax和遍历数组json实例代码
2016/08/01 Javascript
js事件源window.event.srcElement兼容性写法(详解)
2016/11/25 Javascript
Vue获取DOM元素样式和样式更改示例
2017/03/07 Javascript
AngularJS1.X学习笔记2-数据绑定详解
2017/04/01 Javascript
Javascript创建类和对象详解
2017/05/31 Javascript
详解vue中使用express+fetch获取本地json文件
2017/10/10 Javascript
详解微信小程序审核不通过的解决方法
2018/01/17 Javascript
深入浅析Vue中的slots/scoped slots
2018/04/03 Javascript
seajs下require书写约定实例分析
2018/05/16 Javascript
Nodejs中怎么实现函数的串行执行
2019/03/02 NodeJs
vue中js判断长时间不操作界面自动退出登录(推荐)
2020/01/22 Javascript
python中列表元素连接方法join用法实例
2015/04/07 Python
python中redis的安装和使用
2016/12/04 Python
详解python调度框架APScheduler使用
2017/03/28 Python
使用Python实现一个栈判断括号是否平衡
2018/08/23 Python
在VS2017中用C#调用python脚本的实现
2019/07/31 Python
python3 深浅copy对比详解
2019/08/12 Python
Python爬虫设置ip代理过程解析
2020/07/20 Python
python 利用toapi库自动生成api
2020/10/19 Python
英国比较机场停车场网站:Airport Parking Essentials
2019/12/01 全球购物
Ibatis如何调用存储过程
2015/05/15 面试题
办公室前台岗位职责范本
2013/12/10 职场文书
求职信范文怎么写
2015/03/19 职场文书
网站文案策划岗位职责
2015/04/14 职场文书
民事撤诉申请书范本
2015/05/18 职场文书
2016年“12.4”法制宣传日活动总结
2016/04/01 职场文书