首頁 > 軟體

pandas中read_sql使用引數進行資料查詢的實現

2022-06-17 14:03:31

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 如下表

paramstyleMeaning
qmarkQuestion mark style, e.g. …WHERE name=?
numericNumeric, positional style, e.g. …WHERE name=:1
namedNamed style, e.g. …WHERE name=:name
formatANSI C printf format codes, e.g. …WHERE name=%s
pyformatPython 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查詢內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com