pandas中read_sql使用参数进行数据查询的实现
作者:飞羽喂马 发布时间:2023-08-01 23:14:08
pandas.read_sql 可以在数据库中执行指定的SQL语句查询或对指定的整张表进行查询,以DataFrame 的类型返回查询结果,这是在跟数据库进行交互操作时很重要的一步——既读取数据,还返回DataFrame方便处理。
要解决的问题: 编写过的SQL语句需要重复使用,这就涉及到参数,使用参数来替换条件,然后根据需要替换参数。
一、之前的处理方法
在没有使用参数之前,我一直使用的是正则法,也就是利用 re.sub 这个方法将需要的SQL内容替换掉,这样的好处就是可以替换任意内容,缺点就是必须每次使用的时候 import re.sub。
from re import sub
import sqlalchemy
import pandas as pd
# 创建数据库连接,这里使用的是pymysql
engine = sqlalchemy.create_engine("mysql+pymysql://username:password@ip:port/store_name")
sql = "select * from test where id = 'pid'"
# 使用 sub 进行数据替换
data = pd.read_sql(sub("pid", '1', sql), engine)
在这里使用的时候 pid 是为了统一处理才用的标识名,这样在以后不管什么时候都只需要对 pid 进行替换即可。
有一点需要注意的是 sub 替换后的传入是字符串,但是传入到 替换到SQL中是不会变的。比如
sql = "select * from test where id = pid" data =
pd.read_sql(sub("pid", '1', sql), engine)
进行 sub("pid", '1',> sql) 操作后 SQL 变成了
sql select * from test where id = 1
如果 id 字段是 int 类型那就没问题,但是如果 id 字段是 char 或 varchar 等其他类型就会出现字段类型是字符串但给的是数字(mysql 很宽容,不一定会报错,但是从数据类型上来说肯定是错了)
二、使用 read_sql 中的 params 传入参数
1.文档说明
pandas.read_sql(sql, con, index_col=None, coerce_float=True, params=None, parse_dates=None, columns=None, chunksize=None)[source]
read_sql 方法中已经有了 params 这个参数,这个就是可以进行参数的传递,具体的描述如下
params : list, tuple or dict, optional, default: None
List of parameters to pass to execute method. The syntax used to pass parameters is database driver dependent. Check your database driver documentation for which of the five syntax styles, described in PEP 249’s paramstyle, is supported. Eg. for psycopg2, uses %(name)s so use params={‘name’ : ‘value’}
意思就是可以使用功能 list, tuple or dict 传递参数,但是如何怎么设置参数和传递参数需要依据使用的数据库引擎。PEP 249’s paramstyle 如下表
paramstyle | Meaning |
---|---|
qmark | Question mark style, e.g. …WHERE name=? |
numeric | Numeric, positional style, e.g. …WHERE name=:1 |
named | Named style, e.g. …WHERE name=:name |
format | ANSI C printf format codes, e.g. …WHERE name=%s |
pyformat | Python extended format codes, e.g. …WHERE name=%(name)s |
总结下就是在SQL语句中使用?, :1, :name, %s, %设置参数,然后在params 使用 list, tuple or dict 进行参数的传递
2.具体的使用
from re import sub
import sqlalchemy
import pandas as pd
# 创建数据库连接
engine = sqlalchemy.create_engine("mysql+pymysql://username:password@ip:port/store_name")
sql = "select * from test where id = %(pid)s"
# 使用 params 进行参数传递
data = pd.read_sql(sql, engine, params={'pid': '1'})
具体的参数就如上面代码所示,使用了 %(pid)s 设置参数,再用params={‘pid’: ‘1’}传递参数,在Stack Overflow上有个提问也是关于这个的,里面还有关于psycopg2 和SQLite 的参数传递。
三、总结对比
之前没有想过使用参数,是因为在SQL中我不仅要替换固定条件,而且有时候需要替换大段的SQL,所以使用 sub 会更灵活也更模糊(传入的是字符串,到了SQL里面数字还是字符串得再处理一遍),但是使用方法自带的参数传递可以很明确的传递正确的数据和数据类型,而且不觉得使用方法自带的参数传递很优雅?
四、字符串的格式化
对于参数的传递还有另外一种就是python中的字符串格式化,format函数可以实现不带参数、带索引参数、带关键字参数,python的字符串格式化可以参考python格式化输出
下面是format的使用示例
in : print("{one} are {two} {three}".format(one='you', two=1, three='pig'))
out: you are 1 pig
这里的1应该为a,但是为了演示传递整数参数
来源:https://blog.csdn.net/qq_35318838/article/details/101056057


猜你喜欢
- 1. goland配置Dockerfile项目中新建Dockerfile文件配置Dockerfile在项目中新建Dockerfile 文件,
- 析构函数当某个对象成为垃圾或者当对象被显式销毁时执行。PHP5中提供的析构函数是__destruct,其与构造方法__construct相对
- java通过mysql的加解密函数实现敏感字段存储1.AES加解密工具类:public class AESUtils {public sta
- MySQL中模式就是数据库SHOW DATABASES;show databases;罗列所有数据库名称CREATE DATABASE &l
- 一、说明压缩和解压缩是日常常用的操作,不管是windows上图形界面的操作,还是linux上用命令来进行压缩解压缩,总的而言都还是比较方便的
- 接口测试返回数据为字典取值接口测试通常需要校验返回数据跟预期结果是否一致,这个时候如果返回数据为字典,那么我们要拿到我们想要的key对应的v
- 我们知道 map 和 filter 是两种有效的 Python 方法来处理可迭代对象。但是,如果你同时使用 map 和 filter,代码可
- 没有多大变动,主要是返回错误信息,以便调用函数部分可以alert出来。据说可以用正则表达式校验,下次再研究下。//-------------
- 本文实例讲述了朴素贝叶斯分类算法原理与Python实现与使用方法。分享给大家供大家参考,具体如下:朴素贝叶斯分类算法1、朴素贝叶斯分类算法原
- 1.如何用函数先定义后调用,定义阶段只检测语法,不执行代码调用阶段,开始执行代码函数都有返回值定义时无参,调用时也是无参定义时有参,调用时也
- 问题背景问题背景是在,由于视频采集端使用的是H264编码采集的裸流,而网络流媒体大多是以FLV为主的直播方式进行的,为了实现实时直播,当前是
- 前言最近因为工作的原因,在做APP购物车下单支付这一块儿.被测试提了一个bug,当点加入购物车点的比较快的时候,同一个商品在购物车中出现了两
- 实例如下所:import osimport xlrdimport xlwtfrom xlutils.copy import copydef
- 1. 用途(?(id/name)yes-pattern|no-pattern)的作用是:对于给出的id或者name,先尝试去匹配
- MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可护展的高性能数据存储解决方案。它的特点是高性能、易部
- 本文实例分析了JS获取年月日时分秒的方法。分享给大家供大家参考,具体如下:var d = new Date();var time = d.g
- 原文:http://www.smashingmagazine.com/ ... emarkable-favicons/翻译:Blank(怿飞
- 目录Java实现上传Excel文件并导出到数据库1、导入依赖2、domain3、utils4、Controller5、xmlJava实现上传
- Docker用于开发Docker不仅用于部署,它还可以用于开发。1、为什么要在开发中使用Docker主要有以下几个原因。 1)一致的开发环境
- 阅读上一篇:打造设计你自己的字体 Ⅱ永远都在寻觅字体设计的灵感。夏天过后,我买了一套便宜的书法钢笔,说服自己,它会让我的鸡爬字产生脱胎换骨的