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,但是为了演示传递整数参数
到此这篇关于pandas中read_sql使用参数进行数据查询的实现的文章就介绍到这了,更多相关pandas read_sql查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!