热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用Pandas高效读取SQL脚本中的数据

本文详细介绍了如何利用Pandas直接读取和解析SQL脚本,提供了一种高效的数据处理方法。该方法适用于各种数据库导出的SQL脚本,并且能够显著提升数据导入的速度和效率。

在实际工作中,有时会遇到需要处理几百MB大小的SQL脚本文件的情况。通常的做法是先将SQL脚本导入数据库,再从数据库中读取数据,但这种方法速度较慢。本文介绍了一种更高效的方法:直接从SQL脚本中读取数据并加载到Pandas DataFrame中。


将SQL脚本文本解析为CSV格式并加载


SQL脚本本质上是一个文本文件,现代计算机可以轻松地将其一次性加载到内存中。通过Python解析SQL脚本并转换为CSV格式,可以快速生成Pandas DataFrame。



注意:本文提供的代码主要针对MySQL数据库(如SQLyog导出的脚本),对于其他类型的数据库,可能需要根据实际情况进行微调。



以下是具体的读取方法:




from io import StringIO
import pandas as pd
import re

def parse_sql_script(sql_file_path, quotechar="'") -> dict:
insert_pattern = re.compile(r"insert +into +`?(\w+?)`?\(", re.I | re.A)
with open(sql_file_path, encoding="utf-8") as f:
sql_cOntent= f.read()
end_pos = -1
dataframes = {}
while True:
match = insert_pattern.search(sql_content, end_pos + 1)
if not match:
break
table_name = match.group(1)
start_pos = match.span()[1] + 1
end_pos = sql_content.find(";", start_pos)
tmp = re.sub(r"\) (values |,)\(", "\n", sql_content[start_pos:end_pos])
tmp = re.sub(r"[()`]", "", tmp)
df = pd.read_csv(StringIO(tmp), quotechar=quotechar)
dfs = dataframes.setdefault(table_name, [])
dfs.append(df)
for table_name, dfs in dataframes.items():
dataframes[table_name] = pd.concat(dfs)
return dataframes


参数:



  • sql_file_path:SQL脚本的文件路径

  • quotechar:脚本中字符串的引号类型,默认为单引号


返回值:


一个字典,键为表名,值为对应的DataFrame对象。


例如,我们可以用以下代码读取名为index_test的表:




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


结果如下图所示:


image-20210119212546592


如果只需要读取特定表的数据,可以修改上述函数以支持按表名读取:




def read_specific_table(sql_file_path, table_name, quotechar="'") -> pd.DataFrame:
insert_pattern = re.compile(r"insert +into +`?(\w+?)`?\(", re.I | re.A)
with open(sql_file_path, encoding="utf-8") as f:
sql_cOntent= f.read()
end_pos = -1
dfs = []
while True:
match = insert_pattern.search(sql_content, end_pos + 1)
if not match:
break
if match.group(1) != table_name:
continue
start_pos = match.span()[1] + 1
end_pos = sql_content.find(";", start_pos)
tmp = re.sub(r"\) (values |,)\(", "\n", sql_content[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:脚本中字符串的引号类型,默认为单引号


返回值:


指定表对应的DataFrame对象。


读取代码示例:




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


结果如下图所示:


image-20210119222939611


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


另一种方法是将SQL脚本转换为SQLite语法的SQL语句,然后通过SQLite连接读取数据。此方法同样适用于MySQL导出的SQL脚本,但对于其他数据库,可能需要根据具体情况进行调整。




from sqlalchemy import create_engine
import pandas as pd
import re

def convert_and_load_sql_to_sqlite(sql_file_path):
create_pattern = re.compile("create +table [^;]+;", re.I)
insert_pattern = re.compile("insert +into [^;]+;", re.I)
with open(sql_file_path, encoding="utf-8") as f:
sql_cOntent= f.read()
engine = create_engine('sqlite:///:memory:')
pos = -1
while True:
match = create_pattern.search(sql_content, pos + 1)
if match:
pos = match.span()[1]
sql = match.group(0).replace("AUTO_INCREMENT", "")
sql = re.sub(r"\).+;", ");", sql)
engine.execute(sql)
match = insert_pattern.search(sql_content, pos + 1)
if match:
pos = match.span()[1]
sql = match.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= convert_and_load_sql_to_sqlite("D:/tmp/test.sql")
tablename = tablenames[0]
print(tablename)
df = pd.read_sql(f"select * from {tablename};", conn)
df


结果如下图所示:


image-20210119234403297


推荐阅读
  • 本文介绍如何在SQL Server中对Name列进行排序,使特定值(如Default Deliverable Submission Notification)显示在结果集的顶部。 ... [详细]
  • 本文介绍如何使用 Python 的 xlrd 库读取 Excel 文件,并将其数据处理后存储到数据库中。通过实际案例,详细讲解了文件路径、合并单元格处理等常见问题。 ... [详细]
  • 本文探讨了在使用 Django 进行数据库迁移时遇到的常见问题,特别是当出现不一致的迁移历史记录时,如何通过删除所有表并重新进行迁移来解决问题。同时,提供详细的步骤和最佳实践,帮助开发者顺利解决此类问题。 ... [详细]
  • 在学习网页爬虫时,使用Selenium进行自动化操作。初次安装selenium模块后,第二天运行代码时遇到了ImportError:无法从'selenium'导入名称'webdriver'。本文将详细解释该问题的原因及解决方案。 ... [详细]
  • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
  • Python 异步编程:ASGI 服务器与框架详解
    自 Python 3.5 引入 async/await 语法以来,异步编程迅速崛起,吸引了大量开发者的关注。本文将深入探讨 ASGI(异步服务器网关接口)及其在现代 Python Web 开发中的应用,介绍主流的 ASGI 服务器和框架。 ... [详细]
  • 通过Web界面管理Linux日志的解决方案
    本指南介绍了一种利用rsyslog、MariaDB和LogAnalyzer搭建集中式日志管理平台的方法,使用户可以通过Web界面查看和分析Linux系统的日志记录。此方案不仅适用于服务器环境,还提供了详细的步骤来确保系统的稳定性和安全性。 ... [详细]
  • HBase运维工具全解析
    本文深入探讨了HBase常用的运维工具,详细介绍了每种工具的功能、使用场景及操作示例。对于HBase的开发人员和运维工程师来说,这些工具是日常管理和故障排查的重要手段。 ... [详细]
  • 本文详细介绍了Python中函数的基本概念,包括函数的定义与调用、文档注释、参数传递(形参与实参)、返回值以及函数嵌套。通过具体示例和解释,帮助读者掌握函数在编程中的应用。 ... [详细]
  • 对象自省自省在计算机编程领域里,是指在运行时判断一个对象的类型和能力。dir能够返回一个列表,列举了一个对象所拥有的属性和方法。my_list[ ... [详细]
  • 分享一个简化版的Silverlight链接图项目:Link Map Simplified
    本文介绍了一个使用Silverlight开发的可视化工具,主要用于展示和操作复杂的实体关系图(Graph)。该工具在犯罪调查系统中得到了广泛应用,帮助用户直观地获取和理解相关信息。 ... [详细]
  • 深入理解T-SQL中的NULL与三值逻辑
    本文探讨了SQL Server中的三值逻辑,解释了谓词计算结果为TRUE、FALSE和UNKNOWN的规则。通过具体示例,详细说明了如何正确处理NULL值,并探讨了在不同约束条件下的行为。 ... [详细]
  • 创建项目:Visual Studio Online 入门指南
    本文介绍如何使用微软的 Visual Studio Online(VSO)创建和管理开发项目。作为一款基于云计算的开发平台,VSO 提供了丰富的工具和服务,简化了项目的配置和部署流程。 ... [详细]
  • Redis Hash 数据结构详解
    本文详细介绍了 Redis 中的 Hash 数据类型及其常用命令。Hash 类型用于存储键值对集合,支持多种操作如插入、查询、更新和删除字段值。此外,文章还探讨了 Hash 类型在实际业务场景中的应用,并提供了优化建议。 ... [详细]
  • 解决U盘安装系统后无法重启的问题
    本文详细探讨了运维新手常遇到的U盘安装系统后无法正常重启的问题,提供了从问题分析到具体解决方案的完整步骤。通过理解Boot Loader的工作原理和正确配置启动项,帮助用户顺利解决问题。 ... [详细]
author-avatar
谢世雯62956
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有