百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 文章教程 > 正文

使用 Python 增强 SQL 操作的 5 种方法

yund56 2025-04-05 21:39 18 浏览


Python 和 SQL:携手并进,走得更远

尽管有所有关于查询性能优化的内容,但我发现,有时,增强 SQL 功能的最佳方法是将其与 Python 等脚本语言结合起来。

毫无疑问,虽然 SQL 是提取、操作和写入数据库的强大方法,但它缺乏脚本语言的灵活性和实用性,这使得某些操作(例如循环)几乎不可能。

此外,底层数据库的限制可能会降低性能或阻止执行消耗资源的查询。 例如,我曾经遇到过持续存在的过度元读取错误,我将在下面详细说明。

像 Python 这样的脚本语言提供了一种解决方法,它不仅仅可以取代您的 SQL 工作。 结合使用 Python 和 SQL 可以生成更强大、更高效、更清晰的脚本。

循环访问多个 SQL 表

Python 帮助增强 SQL 的最明显方法之一是将查询字符串合并到 Python 的循环结构中,以连续迭代多个查询。

使用 Python 中定义的变量,您可以创建基本查询并使用 SQL 文本和 Python 变量执行操作。

例如,假设我们正在尝试按大小获取 GCP 项目中包含的所有数据集和表格的列表。

在纯 SQL 中,您必须写:

SELECT * FROM `my_project.dataset_1.INFORMATION_SCHEMA`
UNION ALL 
SELECT * FROM `my_project.dataset_2.INFORMATION_SCHEMA`
UNION ALL 
SELECT * FROM `my_project.dataset_3.INFORMATION_SCHEMA`

现在,通过集成Python,我们可以避免一遍又一遍地手动编写这个查询。

from google.cloud import bigquerydatasets = ['dataset_1', 'dataset_2', 'dataset_3']bq_client = bigquery.Client()for dataset in datasets:
    get_datasets = bq_client.query("SELECT dataset_id, table_id,         size_bytes, ROUND(size_bytes / 10000000000), 2) AS gb_size 
FROM `"+dataset.dataset_id+"`.__TABLES__ GROUP BY 1, 2, 3")    tables = get_datasets.result()
    for table in tables:
        dataset_id = table.dataset
        table_id = table.table_id
        size = table.size_bytes
        gb_size = table.gb_size        print(dataset_id, table_id, size, gb_size)

尽管使用两个循环,这可能看起来有些复杂,但我们所做的只是循环访问数据集列表。

我们所更改的只是我们引用的数据集,本质上是创建与 UNION 查询相同的查询,但手动编写较少。

写下来,该操作将如下所示:

""" SELECT dataset_id, table_id, size_bytes, ROUND(size_bytes / 10000000000), 2) AS gb_size 
FROM `my_project.dataset_1.`__TABLES__ GROUP BY 1, 2, 3 """ """ SELECT dataset_id, table_id, size_bytes, ROUND(size_bytes / 10000000000), 2) AS gb_size 
FROM `my_project.dataset_2.`__TABLES__ GROUP BY 1, 2, 3 """""" SELECT dataset_id, table_id, size_bytes, ROUND(size_bytes / 10000000000), 2) AS gb_size 
FROM `my_project.dataset_3.`__TABLES__ GROUP BY 1, 2, 3 """

如果您是处理此实际用例的 BigQuery 用户,您还可以使用 bq_client.list_datasets() 函数生成数据集列表。

需要注意的是,可以在 SQL 中进行循环,但通常必须采取额外的步骤(例如定义变量和创建 UDF)来完成所需的操作。

自动化架构定义

如果你不能通过前面的例子看出,我讨厌多余的操作。 只要有可能,我会尝试使脚本更加高效,并避免多次编写某些内容。

BigQuery Python 客户端允许开发人员将架构定义为列表,稍后可以将其传递给加载函数。

我更喜欢在脚本中定义 BigQuery 架构,而不是默认自动检测,因为 GCP 默认为给定字段提供错误的数据类型,这让我很恼火。

如果您手动定义 BigQuery 架构,它可能如下所示:

schema = [
     bigquery.SchemaField("first_name", "STRING"),
     bigquery.SchemaField("last_name", "STRING"),
     bigquery.SchemaField("age", "INTEGER")]

对于一些领域来说这是可以的。 但当您处理需要 100 列或更多列的数据时,这会变得乏味。

我提出的解决方案是一个相对简单的 Python 函数,它以与我之前描述的循环类似的方式自动填充这些字段。

def create_schema(field_list: list, type_list: list):
    
    schema_list = []
    
    for fields, types in zip(field_list, type_list):
        schema = bigquery.SchemaField(fields, types)
        schema_list.append(schema)        return schema_list

该函数的输出将与上面定义的模式完全相同,但如果我不指定字段是否为 NULLABLE,它将默认为 NULLABLE。

请随意查看我之前的工作,了解该函数的更详细解释、如何调用它以及为什么此方法比手动定义更可取。

只需 1 行 Python 代码即可转换为数据框架

有一种优雅而简单的方法来创建从 SQL 查询派生的数据框架。

更好的是,它只需要一行 Python,特别是如果您将查询存储在外部配置文件中。

query = """ SELECT * FROM `my_project.dataset.table` """ query_job = bq_client.query(cfg.query).to_dataframe()

如果您想保存查询结果,您甚至可以在同一行中将其转换为 CSV。

query_job = bq_client.query(cfg.query).to_dataframe().to_csv('query_output.csv')

至少对我来说,这是一个比必须从 SQL 引擎的 UI 导出或下载报告更简化的过程。

解决 SQL 环境限制

我工作中的第一个“大”项目是自动审计并随后删除数据仓库中未使用的表。

正如您可以想象的那样,这个过程涉及大量元数据。

您可能不知道,BigQuery 对每个作业允许的元读取数量施加了限制。

我经常遇到警告和错误,告诉我无法运行查询,因为它尝试了太多元读取。

起初,我尝试将我的工作分成两个单独的 CTE,但由于它们在同一个查询中运行,我仍然会遇到相同的错误。

然后我的一位高级工程师建议我应该在 Python 中分块运行该东西并使用 Pandas 进行连接。

这种方法非常有效,我最终将整个脚本转换为 Pandas,仅将查询保留为原始数据源。

如果您运行的查询过于消耗资源,请考虑将其拆分为多个部分,在 Python 中运行并使用 Pandas 重新连接。

因为我引用的 CTE 长达数百行并涉及 50 多个元读取,所以我会要求您暂停您的怀疑,只考虑以下示例中操作的查询部分。

query_1 = """ SELECT * FROM a_resource_consuming_cte_1 """ query_2 = """ SELECT * FROM a_resource_consuming_cte_2 """ query_1_df = bq_client.query(query_1).to_dataframe()
query_2_df = bq_client.query(query_2).to_dataframe()final_df = pd.concat([query_1_df, query_2_df]

除了在 Pandas 中进行联接之外,请记住,您可以在 Pandas 中执行几乎所有 SQL 操作,包括更简化的重复数据删除过程。

追加/截断

我过去曾写过相关文章,但我对 BigQuery 的一个主要抱怨是它缺乏对 APPEND/TRUNCATE 操作的支持。

我的意思是我可以将记录添加到表中或覆盖它们。 目前,BigQuery 确实包含一个允许开发人员指定两者的参数。

因此,如果您只想覆盖特定时间范围内的 SQL 表,则需要发挥一点创意。

值得庆幸的是,结合 Python 和 SQL 将使我们能够进行该操作。

在开始编写代码之前,我们先讨论一下为什么需要每天覆盖行。

假设您有一个每天更新多次的电子表格,并且在每天结束时,您希望上传当天日期的条目结果。

由于工作表每天可以编辑多次,因此简单地附加数据会产生重复的行,从而导致数据混乱。

理想情况下,您希望在加载数据时消除任何重复项。

最简单的方法是将 CRUD 语句与 Python/Pandas 代码配对,该代码将创建我们想要覆盖的数据的子集。

crud_statement = """ DELETE FROM table WHERE date = CURRENT_DATE() """ bq_client.query(crud_statement)df = df[(df['date'] == date.today())]bq_client.load_table_from_dataframe(df, job_config)

反过来,这将使您的数据幂等并反映每次运行脚本时的实时更改。

回顾与要点

将 Python 等脚本语言与 SQL 相结合,可以为仅使用 SQL 无法完成的操作开辟新的可能性。

由于许多数据作业不仅需要 SQL 知识,还至少需要 Python 等脚本语言的中级知识,因此您必须了解并希望能够体会到 SQL 和 Python 相结合的强大功能。

SQL 和 Python 的一些用例包括:

循环动态变量

自动执行繁

琐的数据库任务,例如模式自动化

转换为数据框并导出结果

解决环境造成的资源限制

执行自定义加载操作,例如追加/截断

当您继续学习 SQL 时,我鼓励您考虑如何将 Python 的处理能力与 SQL 的精度和实用性结合起来的用例。

相关推荐

仍需打磨:首款Windows 10X模拟器上手

今天,微软发布了适用于Windows10X的首款模拟器,以便于开发人员初步了解适用于双屏设备的操作系统调整。微软希望在SurfaceNeo今年年底正式发售之前,让开发人员对应用程序进行优化。因此...

Windows10 编译OpenCV4.5源码

在OpenCV4.5+VisualStudio2017开发环境配置中,介绍了OpenCV4.5的下载和安装,待扩展内容OpenCV源码编译,在本文中做补充。研究源码无疑是学习OpenCV的一...

微软7年磨一剑,Windows 10X抢先上手体验

2月22日消息,微软在去年10月正式推出了Windows10X系统,该系统除了可用于传统的电脑外,同样适用于双屏设备或者折叠屏设备,拥有更好的触控操作体验。Windows10X在操作系统底层、命令...

Office重新设计了图标,你觉得如何?

微软重新设计了Office的应用图标,在接下来的几个月里,这些图标将从移动端和网页端开始陆续推广至各大平台。距离Office图标的最近一次更新还是在2013年,那时鲍尔默时代的产物,那时微软还在纠结是...

微软发布 Win10 Build 21376 内测版:重新设计默认用户界面字体

IT之家5月7日消息今年早些时候,微软意外地确认正在为Windows10进行UI改进,并在预览版中发现了相关的非活动代码。微软今天宣布向开发渠道中的内测用户发布Windows1...

前端开发需要了解常用7种JavaScript设计模式

作者|Deven译者|王强策划|小智转发链接:https://mp.weixin.qq.com/s/Lw4D7bfUSw_kPoJMD6W8gg前言JavaScript中的设计模式指的是...

「Qt入门第二篇」基础(二)编写Qt多窗口程序

导语程序要实现的功能是:程序开始出现一个对话框,按下按钮后便能进入主窗口,如果直接关闭这个对话框,便不能进入主窗口,整个程序也将退出。当进入主窗口后,我们按下按钮,会弹出一个对话框,无论如何关闭这个对...

在吴中 ,哪里有学网页设计的培训班?

网页设计介绍Web2.0标准布局之网页长期签约就业班(全日制)课程收费:7680元课程周期:5-6个月(45分钟/课)使用教材:《教师自编教材》考核发证:Adobe《网页设计师》培训内容第一部份:...

Qt快速入门(工程的创建、UI界面布局、多线程、项目)

本文档将介绍QT工程的创建、UI界面布局,并以计数器为例了解QT中多线程的用法,最终完成一个基础的QT项目。1创建QT工程文件在安装好QT之后,能够在其安装组件中找到QtCreator,点击设置项...

应用崩溃有救啦!Windows新更新将解决应用崩溃问题

【CNMO新闻】对于不少上班族来说,当自己的电脑在运行某个应用程序时,突然出现应用程序崩溃问题,常常会让人十分苦恼。尤其是对于设计师或者编辑,当自己的作品未能及时保存应用崩溃全部消失的时候,简直就是痛...

Python Qt GUI设计:窗口布局管理方法【强化】(基础篇—6)

在PythonQtGUI设计:窗口布局管理方法【基础篇】(基础篇—5)文章中,聊到了如何使用QtDesigner进行窗口布局管理,其实在QtDesigner中可以非常方便进行窗口布局管理设计,...

思考:如何设计游戏业务框架

虽然现在连主机游戏都纷纷加入了网战部分,不过其身份主要充当状态同步,矛盾点集中在同步即时性上。以大量数值逻辑为主的业务功能侧重点则不同。如果说写代码就是用状态的操作给问题建模,那么编程范式和设计模式种...

用.NET设计一个假装黑客的屏幕保护程序

本文主要介绍屏幕保护程序的一些相关知识,以及其在安全方面的用途,同时介绍了如何使用.NET开发一款屏幕保护程序,并对核心功能做了介绍,案例代码开源:https://github.com/sangy...

光的艺术:灯具创意设计

本文转自|艺术与设计微信号|artdesign_org_cn“光”是文明的起源,是思维的开端,同样也是人类睁眼的开始。每个人在出生一刻,便接受了光的照耀和洗礼。远古时候,人们将光奉为神明,用火来...

Python Qt GUI设计:将UI文件转换Python文件三种妙招(基础篇—2)

在开始本文之前提醒各位朋友,Python记得安装PyQt5库文件,Python语言功能很强,但是Python自带的GUI开发库Tkinter功能很弱,难以开发出专业的GUI。好在Python语言的开放...